1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "FwmarkServer.h" 18 19 #include "Fwmark.h" 20 #include "FwmarkCommand.h" 21 #include "NetdConstants.h" 22 #include "NetworkController.h" 23 #include "TrafficController.h" 24 #include "resolv_netid.h" 25 26 #include <netinet/in.h> 27 #include <selinux/selinux.h> 28 #include <sys/socket.h> 29 #include <unistd.h> 30 #include <utils/String16.h> 31 32 #include <binder/IServiceManager.h> 33 34 using android::String16; 35 using android::net::metrics::INetdEventListener; 36 37 namespace android { 38 namespace net { 39 40 constexpr const char *UPDATE_DEVICE_STATS = "android.permission.UPDATE_DEVICE_STATS"; 41 constexpr const char *SYSTEM_SERVER_CONTEXT = "u:r:system_server:s0"; 42 43 bool isSystemServer(SocketClient* client) { 44 if (client->getUid() != AID_SYSTEM) { 45 return false; 46 } 47 48 char *context; 49 if (getpeercon(client->getSocket(), &context)) { 50 return false; 51 } 52 53 // We can't use context_new and context_type_get as they're private to libselinux. So just do 54 // a string match instead. 55 bool ret = !strcmp(context, SYSTEM_SERVER_CONTEXT); 56 freecon(context); 57 58 return ret; 59 } 60 61 bool hasUpdateDeviceStatsPermission(SocketClient* client) { 62 // If the caller is the system server, allow without any further checks. 63 // Otherwise, if the system server's binder thread pool is full, and all the threads are 64 // blocked on a thread that's waiting for us to complete, we deadlock. http://b/69389492 65 return isSystemServer(client) || 66 checkPermission(String16(UPDATE_DEVICE_STATS), client->getPid(), client->getUid()); 67 } 68 69 FwmarkServer::FwmarkServer(NetworkController* networkController, EventReporter* eventReporter, 70 TrafficController* trafficCtrl) 71 : SocketListener(SOCKET_NAME, true), 72 mNetworkController(networkController), 73 mEventReporter(eventReporter), 74 mTrafficCtrl(trafficCtrl) {} 75 76 bool FwmarkServer::onDataAvailable(SocketClient* client) { 77 int socketFd = -1; 78 int error = processClient(client, &socketFd); 79 if (socketFd >= 0) { 80 close(socketFd); 81 } 82 83 // Always send a response even if there were connection errors or read errors, so that we don't 84 // inadvertently cause the client to hang (which always waits for a response). 85 client->sendData(&error, sizeof(error)); 86 87 // Always close the client connection (by returning false). This prevents a DoS attack where 88 // the client issues multiple commands on the same connection, never reading the responses, 89 // causing its receive buffer to fill up, and thus causing our client->sendData() to block. 90 return false; 91 } 92 93 int FwmarkServer::processClient(SocketClient* client, int* socketFd) { 94 FwmarkCommand command; 95 FwmarkConnectInfo connectInfo; 96 97 iovec iov[2] = { 98 { &command, sizeof(command) }, 99 { &connectInfo, sizeof(connectInfo) }, 100 }; 101 msghdr message; 102 memset(&message, 0, sizeof(message)); 103 message.msg_iov = iov; 104 message.msg_iovlen = ARRAY_SIZE(iov); 105 106 union { 107 cmsghdr cmh; 108 char cmsg[CMSG_SPACE(sizeof(*socketFd))]; 109 } cmsgu; 110 111 memset(cmsgu.cmsg, 0, sizeof(cmsgu.cmsg)); 112 message.msg_control = cmsgu.cmsg; 113 message.msg_controllen = sizeof(cmsgu.cmsg); 114 115 int messageLength = TEMP_FAILURE_RETRY(recvmsg(client->getSocket(), &message, MSG_CMSG_CLOEXEC)); 116 if (messageLength <= 0) { 117 return -errno; 118 } 119 120 if (!((command.cmdId != FwmarkCommand::ON_CONNECT_COMPLETE && messageLength == sizeof(command)) 121 || (command.cmdId == FwmarkCommand::ON_CONNECT_COMPLETE 122 && messageLength == sizeof(command) + sizeof(connectInfo)))) { 123 return -EBADMSG; 124 } 125 126 Permission permission = mNetworkController->getPermissionForUser(client->getUid()); 127 128 if (command.cmdId == FwmarkCommand::QUERY_USER_ACCESS) { 129 if ((permission & PERMISSION_SYSTEM) != PERMISSION_SYSTEM) { 130 return -EPERM; 131 } 132 return mNetworkController->checkUserNetworkAccess(command.uid, command.netId); 133 } 134 135 if (command.cmdId == FwmarkCommand::SET_COUNTERSET) { 136 if (!hasUpdateDeviceStatsPermission(client)) { 137 return -EPERM; 138 } 139 return mTrafficCtrl->setCounterSet(command.trafficCtrlInfo, command.uid); 140 } 141 142 if (command.cmdId == FwmarkCommand::DELETE_TAGDATA) { 143 if (!hasUpdateDeviceStatsPermission(client)) { 144 return -EPERM; 145 } 146 return mTrafficCtrl->deleteTagData(command.trafficCtrlInfo, command.uid); 147 } 148 149 cmsghdr* const cmsgh = CMSG_FIRSTHDR(&message); 150 if (cmsgh && cmsgh->cmsg_level == SOL_SOCKET && cmsgh->cmsg_type == SCM_RIGHTS && 151 cmsgh->cmsg_len == CMSG_LEN(sizeof(*socketFd))) { 152 memcpy(socketFd, CMSG_DATA(cmsgh), sizeof(*socketFd)); 153 } 154 155 if (*socketFd < 0) { 156 return -EBADF; 157 } 158 159 Fwmark fwmark; 160 socklen_t fwmarkLen = sizeof(fwmark.intValue); 161 if (getsockopt(*socketFd, SOL_SOCKET, SO_MARK, &fwmark.intValue, &fwmarkLen) == -1) { 162 return -errno; 163 } 164 165 switch (command.cmdId) { 166 case FwmarkCommand::ON_ACCEPT: { 167 // Called after a socket accept(). The kernel would've marked the NetId and necessary 168 // permissions bits, so we just add the rest of the user's permissions here. 169 permission = static_cast<Permission>(permission | fwmark.permission); 170 break; 171 } 172 173 case FwmarkCommand::ON_CONNECT: { 174 // Called before a socket connect() happens. Set an appropriate NetId into the fwmark so 175 // that the socket routes consistently over that network. Do this even if the socket 176 // already has a NetId, so that calling connect() multiple times still works. 177 // 178 // But if the explicit bit was set, the existing NetId was explicitly preferred (and not 179 // a case of connect() being called multiple times). Don't reset the NetId in that case. 180 // 181 // An "appropriate" NetId is the NetId of a bypassable VPN that applies to the user, or 182 // failing that, the default network. We'll never set the NetId of a secure VPN here. 183 // See the comments in the implementation of getNetworkForConnect() for more details. 184 // 185 // If the protect bit is set, this could be either a system proxy (e.g.: the dns proxy 186 // or the download manager) acting on behalf of another user, or a VPN provider. If it's 187 // a proxy, we shouldn't reset the NetId. If it's a VPN provider, we should set the 188 // default network's NetId. 189 // 190 // There's no easy way to tell the difference between a proxy and a VPN app. We can't 191 // use PERMISSION_SYSTEM to identify the proxy because a VPN app may also have those 192 // permissions. So we use the following heuristic: 193 // 194 // If it's a proxy, but the existing NetId is not a VPN, that means the user (that the 195 // proxy is acting on behalf of) is not subject to a VPN, so the proxy must have picked 196 // the default network's NetId. So, it's okay to replace that with the current default 197 // network's NetId (which in all likelihood is the same). 198 // 199 // Conversely, if it's a VPN provider, the existing NetId cannot be a VPN. The only time 200 // we set a VPN's NetId into a socket without setting the explicit bit is here, in 201 // ON_CONNECT, but we won't do that if the socket has the protect bit set. If the VPN 202 // provider connect()ed (and got the VPN NetId set) and then called protect(), we 203 // would've unset the NetId in PROTECT_FROM_VPN below. 204 // 205 // So, overall (when the explicit bit is not set but the protect bit is set), if the 206 // existing NetId is a VPN, don't reset it. Else, set the default network's NetId. 207 if (!fwmark.explicitlySelected) { 208 if (!fwmark.protectedFromVpn) { 209 fwmark.netId = mNetworkController->getNetworkForConnect(client->getUid()); 210 } else if (!mNetworkController->isVirtualNetwork(fwmark.netId)) { 211 fwmark.netId = mNetworkController->getDefaultNetwork(); 212 } 213 } 214 break; 215 } 216 217 case FwmarkCommand::ON_CONNECT_COMPLETE: { 218 // Called after a socket connect() completes. 219 // This reports connect event including netId, destination IP address, destination port, 220 // uid, connect latency, and connect errno if any. 221 222 // Skip reporting if connect() happened on a UDP socket. 223 int socketProto; 224 socklen_t intSize = sizeof(socketProto); 225 const int ret = getsockopt(*socketFd, SOL_SOCKET, SO_PROTOCOL, &socketProto, &intSize); 226 if ((ret != 0) || (socketProto == IPPROTO_UDP)) { 227 break; 228 } 229 230 android::sp<android::net::metrics::INetdEventListener> netdEventListener = 231 mEventReporter->getNetdEventListener(); 232 233 if (netdEventListener != nullptr) { 234 char addrstr[INET6_ADDRSTRLEN]; 235 char portstr[sizeof("65536")]; 236 const int ret = getnameinfo((sockaddr*) &connectInfo.addr, sizeof(connectInfo.addr), 237 addrstr, sizeof(addrstr), portstr, sizeof(portstr), 238 NI_NUMERICHOST | NI_NUMERICSERV); 239 240 netdEventListener->onConnectEvent(fwmark.netId, connectInfo.error, 241 connectInfo.latencyMs, 242 (ret == 0) ? String16(addrstr) : String16(""), 243 (ret == 0) ? strtoul(portstr, NULL, 10) : 0, client->getUid()); 244 } 245 break; 246 } 247 248 case FwmarkCommand::SELECT_NETWORK: { 249 fwmark.netId = command.netId; 250 if (command.netId == NETID_UNSET) { 251 fwmark.explicitlySelected = false; 252 fwmark.protectedFromVpn = false; 253 permission = PERMISSION_NONE; 254 } else { 255 if (int ret = mNetworkController->checkUserNetworkAccess(client->getUid(), 256 command.netId)) { 257 return ret; 258 } 259 fwmark.explicitlySelected = true; 260 fwmark.protectedFromVpn = mNetworkController->canProtect(client->getUid()); 261 } 262 break; 263 } 264 265 case FwmarkCommand::PROTECT_FROM_VPN: { 266 if (!mNetworkController->canProtect(client->getUid())) { 267 return -EPERM; 268 } 269 // If a bypassable VPN's provider app calls connect() and then protect(), it will end up 270 // with a socket that looks like that of a system proxy but is not (see comments for 271 // ON_CONNECT above). So, reset the NetId. 272 // 273 // In any case, it's appropriate that if the socket has an implicit VPN NetId mark, the 274 // PROTECT_FROM_VPN command should unset it. 275 if (!fwmark.explicitlySelected && mNetworkController->isVirtualNetwork(fwmark.netId)) { 276 fwmark.netId = mNetworkController->getDefaultNetwork(); 277 } 278 fwmark.protectedFromVpn = true; 279 permission = static_cast<Permission>(permission | fwmark.permission); 280 break; 281 } 282 283 case FwmarkCommand::SELECT_FOR_USER: { 284 if ((permission & PERMISSION_SYSTEM) != PERMISSION_SYSTEM) { 285 return -EPERM; 286 } 287 fwmark.netId = mNetworkController->getNetworkForUser(command.uid); 288 fwmark.protectedFromVpn = true; 289 break; 290 } 291 292 case FwmarkCommand::TAG_SOCKET: { 293 // If the UID is -1, tag as the caller's UID: 294 // - TrafficStats and NetworkManagementSocketTagger use -1 to indicate "use the 295 // caller's UID". 296 // - xt_qtaguid will see -1 on the command line, fail to parse it as a uint32_t, and 297 // fall back to current_fsuid(). 298 if (static_cast<int>(command.uid) == -1) { 299 command.uid = client->getUid(); 300 } 301 if (command.uid != client->getUid() && !hasUpdateDeviceStatsPermission(client)) { 302 return -EPERM; 303 } 304 return mTrafficCtrl->tagSocket(*socketFd, command.trafficCtrlInfo, command.uid); 305 } 306 307 case FwmarkCommand::UNTAG_SOCKET: { 308 // Any process can untag a socket it has an fd for. 309 return mTrafficCtrl->untagSocket(*socketFd); 310 } 311 312 default: { 313 // unknown command 314 return -EPROTO; 315 } 316 } 317 318 fwmark.permission = permission; 319 320 if (setsockopt(*socketFd, SOL_SOCKET, SO_MARK, &fwmark.intValue, 321 sizeof(fwmark.intValue)) == -1) { 322 return -errno; 323 } 324 325 return 0; 326 } 327 328 } // namespace net 329 } // namespace android 330