NetworkController.cpp revision 89dad013e4dd98434b0409a84567f38782894029
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// THREAD-SAFETY 18// ------------- 19// The methods in this file are called from multiple threads (from CommandListener, FwmarkServer 20// and DnsProxyListener). So, all accesses to shared state are guarded by a lock. 21// 22// In some cases, a single non-const method acquires and releases the lock several times, like so: 23// if (isValidNetwork(...)) { // isValidNetwork() acquires and releases the lock. 24// setDefaultNetwork(...); // setDefaultNetwork() also acquires and releases the lock. 25// 26// It might seem that this allows races where the state changes between the two statements, but in 27// fact there are no races because: 28// 1. This pattern only occurs in non-const methods (i.e., those that mutate state). 29// 2. Only CommandListener calls these non-const methods. The others call only const methods. 30// 3. CommandListener only processes one command at a time. I.e., it's serialized. 31// Thus, no other mutation can occur in between the two statements above. 32 33#include "NetworkController.h" 34 35#include "PhysicalNetwork.h" 36#include "RouteController.h" 37#include "VirtualNetwork.h" 38 39#define LOG_TAG "Netd" 40#include "log/log.h" 41#include "resolv_netid.h" 42 43namespace { 44 45// Keep these in sync with ConnectivityService.java. 46const unsigned MIN_NET_ID = 10; 47const unsigned MAX_NET_ID = 65535; 48 49} // namespace 50 51NetworkController::NetworkController() : mDefaultNetId(NETID_UNSET) { 52} 53 54unsigned NetworkController::getDefaultNetwork() const { 55 android::RWLock::AutoRLock lock(mRWLock); 56 return mDefaultNetId; 57} 58 59int NetworkController::setDefaultNetwork(unsigned netId) { 60 android::RWLock::AutoWLock lock(mRWLock); 61 62 if (netId == mDefaultNetId) { 63 return 0; 64 } 65 66 if (netId != NETID_UNSET) { 67 Network* network = getNetworkLocked(netId); 68 if (!network || network->getType() != Network::PHYSICAL) { 69 ALOGE("invalid netId %u", netId); 70 return -EINVAL; 71 } 72 if (int ret = static_cast<PhysicalNetwork*>(network)->addAsDefault()) { 73 return ret; 74 } 75 } 76 77 if (mDefaultNetId != NETID_UNSET) { 78 Network* network = getNetworkLocked(mDefaultNetId); 79 if (!network || network->getType() != Network::PHYSICAL) { 80 ALOGE("cannot find previously set default network with netId %u", mDefaultNetId); 81 return -ESRCH; 82 } 83 if (int ret = static_cast<PhysicalNetwork*>(network)->removeAsDefault()) { 84 return ret; 85 } 86 } 87 88 mDefaultNetId = netId; 89 return 0; 90} 91 92bool NetworkController::setNetworkForUidRange(uid_t uidStart, uid_t uidEnd, unsigned netId, 93 bool forwardDns) { 94 if (uidStart > uidEnd || !isValidNetwork(netId)) { 95 errno = EINVAL; 96 return false; 97 } 98 99 android::RWLock::AutoWLock lock(mRWLock); 100 for (UidEntry& entry : mUidMap) { 101 if (entry.uidStart == uidStart && entry.uidEnd == uidEnd && entry.netId == netId) { 102 entry.forwardDns = forwardDns; 103 return true; 104 } 105 } 106 107 mUidMap.push_front(UidEntry(uidStart, uidEnd, netId, forwardDns)); 108 return true; 109} 110 111bool NetworkController::clearNetworkForUidRange(uid_t uidStart, uid_t uidEnd, unsigned netId) { 112 if (uidStart > uidEnd || !isValidNetwork(netId)) { 113 errno = EINVAL; 114 return false; 115 } 116 117 android::RWLock::AutoWLock lock(mRWLock); 118 for (auto iter = mUidMap.begin(); iter != mUidMap.end(); ++iter) { 119 if (iter->uidStart == uidStart && iter->uidEnd == uidEnd && iter->netId == netId) { 120 mUidMap.erase(iter); 121 return true; 122 } 123 } 124 125 errno = ENOENT; 126 return false; 127} 128 129unsigned NetworkController::getNetwork(uid_t uid, unsigned requestedNetId, bool forDns) const { 130 android::RWLock::AutoRLock lock(mRWLock); 131 for (const UidEntry& entry : mUidMap) { 132 if (entry.uidStart <= uid && uid <= entry.uidEnd) { 133 if (forDns && !entry.forwardDns) { 134 break; 135 } 136 return entry.netId; 137 } 138 } 139 return getNetworkLocked(requestedNetId) ? requestedNetId : mDefaultNetId; 140} 141 142unsigned NetworkController::getNetworkId(const char* interface) const { 143 android::RWLock::AutoRLock lock(mRWLock); 144 for (const auto& entry : mNetworks) { 145 if (entry.second->hasInterface(interface)) { 146 return entry.first; 147 } 148 } 149 return NETID_UNSET; 150} 151 152bool NetworkController::isValidNetwork(unsigned netId) const { 153 android::RWLock::AutoRLock lock(mRWLock); 154 return getNetworkLocked(netId); 155} 156 157int NetworkController::createNetwork(unsigned netId, Permission permission) { 158 if (netId < MIN_NET_ID || netId > MAX_NET_ID) { 159 ALOGE("invalid netId %u", netId); 160 return -EINVAL; 161 } 162 163 if (isValidNetwork(netId)) { 164 ALOGE("duplicate netId %u", netId); 165 return -EEXIST; 166 } 167 168 PhysicalNetwork* physicalNetwork = new PhysicalNetwork(netId); 169 if (int ret = physicalNetwork->setPermission(permission)) { 170 ALOGE("inconceivable! setPermission cannot fail on an empty network"); 171 delete physicalNetwork; 172 return ret; 173 } 174 175 android::RWLock::AutoWLock lock(mRWLock); 176 mNetworks[netId] = physicalNetwork; 177 return 0; 178} 179 180int NetworkController::createVpn(unsigned netId) { 181 if (netId < MIN_NET_ID || netId > MAX_NET_ID) { 182 ALOGE("invalid netId %u", netId); 183 return -EINVAL; 184 } 185 186 if (isValidNetwork(netId)) { 187 ALOGE("duplicate netId %u", netId); 188 return -EEXIST; 189 } 190 191 android::RWLock::AutoWLock lock(mRWLock); 192 mNetworks[netId] = new VirtualNetwork(netId); 193 return 0; 194} 195 196int NetworkController::destroyNetwork(unsigned netId) { 197 if (!isValidNetwork(netId)) { 198 ALOGE("invalid netId %u", netId); 199 return -EINVAL; 200 } 201 202 // TODO: ioctl(SIOCKILLADDR, ...) to kill all sockets on the old network. 203 204 android::RWLock::AutoWLock lock(mRWLock); 205 Network* network = getNetworkLocked(netId); 206 if (int ret = network->clearInterfaces()) { 207 return ret; 208 } 209 if (mDefaultNetId == netId) { 210 if (int ret = static_cast<PhysicalNetwork*>(network)->removeAsDefault()) { 211 ALOGE("inconceivable! removeAsDefault cannot fail on an empty network"); 212 return ret; 213 } 214 mDefaultNetId = NETID_UNSET; 215 } 216 mNetworks.erase(netId); 217 delete network; 218 _resolv_delete_cache_for_net(netId); 219 return 0; 220} 221 222int NetworkController::addInterfaceToNetwork(unsigned netId, const char* interface) { 223 if (!isValidNetwork(netId)) { 224 ALOGE("invalid netId %u", netId); 225 return -EINVAL; 226 } 227 228 unsigned existingNetId = getNetworkId(interface); 229 if (existingNetId != NETID_UNSET && existingNetId != netId) { 230 ALOGE("interface %s already assigned to netId %u", interface, existingNetId); 231 return -EBUSY; 232 } 233 234 android::RWLock::AutoWLock lock(mRWLock); 235 return getNetworkLocked(netId)->addInterface(interface); 236} 237 238int NetworkController::removeInterfaceFromNetwork(unsigned netId, const char* interface) { 239 if (!isValidNetwork(netId)) { 240 ALOGE("invalid netId %u", netId); 241 return -EINVAL; 242 } 243 244 android::RWLock::AutoWLock lock(mRWLock); 245 return getNetworkLocked(netId)->removeInterface(interface); 246} 247 248Permission NetworkController::getPermissionForUser(uid_t uid) const { 249 android::RWLock::AutoRLock lock(mRWLock); 250 auto iter = mUsers.find(uid); 251 return iter == mUsers.end() ? PERMISSION_NONE : iter->second; 252} 253 254void NetworkController::setPermissionForUsers(Permission permission, 255 const std::vector<uid_t>& uids) { 256 android::RWLock::AutoWLock lock(mRWLock); 257 for (uid_t uid : uids) { 258 if (permission == PERMISSION_NONE) { 259 mUsers.erase(uid); 260 } else { 261 mUsers[uid] = permission; 262 } 263 } 264} 265 266// TODO: Handle VPNs. 267bool NetworkController::isUserPermittedOnNetwork(uid_t uid, unsigned netId) const { 268 android::RWLock::AutoRLock lock(mRWLock); 269 auto userIter = mUsers.find(uid); 270 Permission userPermission = (userIter == mUsers.end() ? PERMISSION_NONE : userIter->second); 271 Network* network = getNetworkLocked(netId); 272 if (!network || network->getType() != Network::PHYSICAL) { 273 return false; 274 } 275 Permission networkPermission = static_cast<PhysicalNetwork*>(network)->getPermission(); 276 return (userPermission & networkPermission) == networkPermission; 277} 278 279int NetworkController::setPermissionForNetworks(Permission permission, 280 const std::vector<unsigned>& netIds) { 281 android::RWLock::AutoWLock lock(mRWLock); 282 for (unsigned netId : netIds) { 283 Network* network = getNetworkLocked(netId); 284 if (!network || network->getType() != Network::PHYSICAL) { 285 ALOGE("invalid netId %u", netId); 286 return -EINVAL; 287 } 288 289 // TODO: ioctl(SIOCKILLADDR, ...) to kill socets on the network that don't have permission. 290 291 if (int ret = static_cast<PhysicalNetwork*>(network)->setPermission(permission)) { 292 return ret; 293 } 294 } 295 return 0; 296} 297 298int NetworkController::addUsersToNetwork(unsigned netId, const UidRanges& uidRanges) { 299 android::RWLock::AutoWLock lock(mRWLock); 300 Network* network = getNetworkLocked(netId); 301 if (!network || network->getType() != Network::VIRTUAL) { 302 ALOGE("invalid netId %u", netId); 303 return -EINVAL; 304 } 305 if (int ret = static_cast<VirtualNetwork*>(network)->addUsers(uidRanges)) { 306 return ret; 307 } 308 return 0; 309} 310 311int NetworkController::removeUsersFromNetwork(unsigned netId, const UidRanges& uidRanges) { 312 android::RWLock::AutoWLock lock(mRWLock); 313 Network* network = getNetworkLocked(netId); 314 if (!network || network->getType() != Network::VIRTUAL) { 315 ALOGE("invalid netId %u", netId); 316 return -EINVAL; 317 } 318 if (int ret = static_cast<VirtualNetwork*>(network)->removeUsers(uidRanges)) { 319 return ret; 320 } 321 return 0; 322} 323 324int NetworkController::addRoute(unsigned netId, const char* interface, const char* destination, 325 const char* nexthop, bool legacy, uid_t uid) { 326 return modifyRoute(netId, interface, destination, nexthop, true, legacy, uid); 327} 328 329int NetworkController::removeRoute(unsigned netId, const char* interface, const char* destination, 330 const char* nexthop, bool legacy, uid_t uid) { 331 return modifyRoute(netId, interface, destination, nexthop, false, legacy, uid); 332} 333 334void NetworkController::allowProtect(const std::vector<uid_t>& uids) { 335 android::RWLock::AutoWLock lock(mRWLock); 336 mProtectableUsers.insert(uids.begin(), uids.end()); 337} 338 339void NetworkController::denyProtect(const std::vector<uid_t>& uids) { 340 android::RWLock::AutoWLock lock(mRWLock); 341 for (uid_t uid : uids) { 342 mProtectableUsers.erase(uid); 343 } 344} 345 346Network* NetworkController::getNetworkLocked(unsigned netId) const { 347 auto iter = mNetworks.find(netId); 348 return iter == mNetworks.end() ? NULL : iter->second; 349} 350 351int NetworkController::modifyRoute(unsigned netId, const char* interface, const char* destination, 352 const char* nexthop, bool add, bool legacy, uid_t uid) { 353 unsigned existingNetId = getNetworkId(interface); 354 if (netId == NETID_UNSET || existingNetId != netId) { 355 ALOGE("interface %s assigned to netId %u, not %u", interface, existingNetId, netId); 356 return -ENOENT; 357 } 358 359 RouteController::TableType tableType; 360 if (legacy) { 361 if (getPermissionForUser(uid) & PERMISSION_CONNECTIVITY_INTERNAL) { 362 tableType = RouteController::PRIVILEGED_LEGACY; 363 } else { 364 tableType = RouteController::LEGACY; 365 } 366 } else { 367 tableType = RouteController::INTERFACE; 368 } 369 370 return add ? RouteController::addRoute(interface, destination, nexthop, tableType) : 371 RouteController::removeRoute(interface, destination, nexthop, tableType); 372} 373 374NetworkController::UidEntry::UidEntry(uid_t uidStart, uid_t uidEnd, unsigned netId, 375 bool forwardDns) : 376 uidStart(uidStart), uidEnd(uidEnd), netId(netId), forwardDns(forwardDns) { 377} 378