NetworkController.cpp revision 6a773534e7f8541f221f27fb8063af079b1a5936
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 "LocalNetwork.h" 36#include "PhysicalNetwork.h" 37#include "RouteController.h" 38#include "VirtualNetwork.h" 39 40#include "cutils/misc.h" 41#define LOG_TAG "Netd" 42#include "log/log.h" 43#include "resolv_netid.h" 44 45namespace { 46 47// Keep these in sync with ConnectivityService.java. 48const unsigned MIN_NET_ID = 10; 49const unsigned MAX_NET_ID = 65535; 50 51} // namespace 52 53NetworkController::NetworkController() : mDefaultNetId(NETID_UNSET) { 54} 55 56unsigned NetworkController::getDefaultNetwork() const { 57 android::RWLock::AutoRLock lock(mRWLock); 58 return mDefaultNetId; 59} 60 61int NetworkController::setDefaultNetwork(unsigned netId) { 62 android::RWLock::AutoWLock lock(mRWLock); 63 64 if (netId == mDefaultNetId) { 65 return 0; 66 } 67 68 if (netId != NETID_UNSET) { 69 Network* network = getNetworkLocked(netId); 70 if (!network || network->getType() != Network::PHYSICAL) { 71 ALOGE("invalid netId %u", netId); 72 return -EINVAL; 73 } 74 if (int ret = static_cast<PhysicalNetwork*>(network)->addAsDefault()) { 75 return ret; 76 } 77 } 78 79 if (mDefaultNetId != NETID_UNSET) { 80 Network* network = getNetworkLocked(mDefaultNetId); 81 if (!network || network->getType() != Network::PHYSICAL) { 82 ALOGE("cannot find previously set default network with netId %u", mDefaultNetId); 83 return -ESRCH; 84 } 85 if (int ret = static_cast<PhysicalNetwork*>(network)->removeAsDefault()) { 86 return ret; 87 } 88 } 89 90 mDefaultNetId = netId; 91 return 0; 92} 93 94unsigned NetworkController::getNetworkForUser(uid_t uid, unsigned requestedNetId, 95 bool forDns) const { 96 android::RWLock::AutoRLock lock(mRWLock); 97 VirtualNetwork* virtualNetwork = getVirtualNetworkForUserLocked(uid); 98 if (virtualNetwork && (!forDns || virtualNetwork->getHasDns())) { 99 return virtualNetwork->getNetId(); 100 } 101 return getNetworkLocked(requestedNetId) ? requestedNetId : mDefaultNetId; 102} 103 104unsigned NetworkController::getNetworkForInterface(const char* interface) const { 105 android::RWLock::AutoRLock lock(mRWLock); 106 for (const auto& entry : mNetworks) { 107 if (entry.second->hasInterface(interface)) { 108 return entry.first; 109 } 110 } 111 return NETID_UNSET; 112} 113 114unsigned NetworkController::getNetIdForLocalNetwork() const { 115 return MIN_NET_ID - 1; 116} 117 118int NetworkController::createLocalNetwork(unsigned netId) { 119 // TODO: Enable this check after removing the getNetIdForLocalNetwork() hack. 120 if (false) { 121 if (netId < MIN_NET_ID || netId > MAX_NET_ID) { 122 ALOGE("invalid netId %u", netId); 123 return -EINVAL; 124 } 125 } 126 127 if (isValidNetwork(netId)) { 128 ALOGE("duplicate netId %u", netId); 129 return -EEXIST; 130 } 131 132 android::RWLock::AutoWLock lock(mRWLock); 133 mNetworks[netId] = new LocalNetwork(netId); 134 return 0; 135} 136 137int NetworkController::createPhysicalNetwork(unsigned netId, Permission permission) { 138 if (netId < MIN_NET_ID || netId > MAX_NET_ID) { 139 ALOGE("invalid netId %u", netId); 140 return -EINVAL; 141 } 142 143 if (isValidNetwork(netId)) { 144 ALOGE("duplicate netId %u", netId); 145 return -EEXIST; 146 } 147 148 PhysicalNetwork* physicalNetwork = new PhysicalNetwork(netId); 149 if (int ret = physicalNetwork->setPermission(permission)) { 150 ALOGE("inconceivable! setPermission cannot fail on an empty network"); 151 delete physicalNetwork; 152 return ret; 153 } 154 155 android::RWLock::AutoWLock lock(mRWLock); 156 mNetworks[netId] = physicalNetwork; 157 return 0; 158} 159 160int NetworkController::createVirtualNetwork(unsigned netId, bool hasDns) { 161 if (netId < MIN_NET_ID || netId > MAX_NET_ID) { 162 ALOGE("invalid netId %u", netId); 163 return -EINVAL; 164 } 165 166 if (isValidNetwork(netId)) { 167 ALOGE("duplicate netId %u", netId); 168 return -EEXIST; 169 } 170 171 android::RWLock::AutoWLock lock(mRWLock); 172 mNetworks[netId] = new VirtualNetwork(netId, hasDns); 173 return 0; 174} 175 176int NetworkController::destroyNetwork(unsigned netId) { 177 if (!isValidNetwork(netId)) { 178 ALOGE("invalid netId %u", netId); 179 return -EINVAL; 180 } 181 182 // TODO: ioctl(SIOCKILLADDR, ...) to kill all sockets on the old network. 183 184 android::RWLock::AutoWLock lock(mRWLock); 185 Network* network = getNetworkLocked(netId); 186 if (int ret = network->clearInterfaces()) { 187 return ret; 188 } 189 if (mDefaultNetId == netId) { 190 if (int ret = static_cast<PhysicalNetwork*>(network)->removeAsDefault()) { 191 ALOGE("inconceivable! removeAsDefault cannot fail on an empty network"); 192 return ret; 193 } 194 mDefaultNetId = NETID_UNSET; 195 } 196 mNetworks.erase(netId); 197 delete network; 198 _resolv_delete_cache_for_net(netId); 199 return 0; 200} 201 202int NetworkController::addInterfaceToNetwork(unsigned netId, const char* interface) { 203 if (!isValidNetwork(netId)) { 204 ALOGE("invalid netId %u", netId); 205 return -EINVAL; 206 } 207 208 unsigned existingNetId = getNetworkForInterface(interface); 209 if (existingNetId != NETID_UNSET && existingNetId != netId) { 210 ALOGE("interface %s already assigned to netId %u", interface, existingNetId); 211 return -EBUSY; 212 } 213 214 android::RWLock::AutoWLock lock(mRWLock); 215 return getNetworkLocked(netId)->addInterface(interface); 216} 217 218int NetworkController::removeInterfaceFromNetwork(unsigned netId, const char* interface) { 219 if (!isValidNetwork(netId)) { 220 ALOGE("invalid netId %u", netId); 221 return -EINVAL; 222 } 223 224 android::RWLock::AutoWLock lock(mRWLock); 225 return getNetworkLocked(netId)->removeInterface(interface); 226} 227 228Permission NetworkController::getPermissionForUser(uid_t uid) const { 229 android::RWLock::AutoRLock lock(mRWLock); 230 return getPermissionForUserLocked(uid); 231} 232 233void NetworkController::setPermissionForUsers(Permission permission, 234 const std::vector<uid_t>& uids) { 235 android::RWLock::AutoWLock lock(mRWLock); 236 for (uid_t uid : uids) { 237 mUsers[uid] = permission; 238 } 239} 240 241bool NetworkController::canUserSelectNetwork(uid_t uid, unsigned netId) const { 242 android::RWLock::AutoRLock lock(mRWLock); 243 Network* network = getNetworkLocked(netId); 244 if (!network || uid == INVALID_UID) { 245 return false; 246 } 247 Permission userPermission = getPermissionForUserLocked(uid); 248 if ((userPermission & PERMISSION_SYSTEM) == PERMISSION_SYSTEM) { 249 return true; 250 } 251 if (network->getType() == Network::VIRTUAL) { 252 return static_cast<VirtualNetwork*>(network)->appliesToUser(uid); 253 } 254 VirtualNetwork* virtualNetwork = getVirtualNetworkForUserLocked(uid); 255 if (virtualNetwork && mProtectableUsers.find(uid) == mProtectableUsers.end()) { 256 return false; 257 } 258 Permission networkPermission = static_cast<PhysicalNetwork*>(network)->getPermission(); 259 return (userPermission & networkPermission) == networkPermission; 260} 261 262int NetworkController::setPermissionForNetworks(Permission permission, 263 const std::vector<unsigned>& netIds) { 264 android::RWLock::AutoWLock lock(mRWLock); 265 for (unsigned netId : netIds) { 266 Network* network = getNetworkLocked(netId); 267 if (!network || network->getType() != Network::PHYSICAL) { 268 ALOGE("invalid netId %u", netId); 269 return -EINVAL; 270 } 271 272 // TODO: ioctl(SIOCKILLADDR, ...) to kill socets on the network that don't have permission. 273 274 if (int ret = static_cast<PhysicalNetwork*>(network)->setPermission(permission)) { 275 return ret; 276 } 277 } 278 return 0; 279} 280 281int NetworkController::addUsersToNetwork(unsigned netId, const UidRanges& uidRanges) { 282 android::RWLock::AutoWLock lock(mRWLock); 283 Network* network = getNetworkLocked(netId); 284 if (!network || network->getType() != Network::VIRTUAL) { 285 ALOGE("invalid netId %u", netId); 286 return -EINVAL; 287 } 288 if (int ret = static_cast<VirtualNetwork*>(network)->addUsers(uidRanges)) { 289 return ret; 290 } 291 return 0; 292} 293 294int NetworkController::removeUsersFromNetwork(unsigned netId, const UidRanges& uidRanges) { 295 android::RWLock::AutoWLock lock(mRWLock); 296 Network* network = getNetworkLocked(netId); 297 if (!network || network->getType() != Network::VIRTUAL) { 298 ALOGE("invalid netId %u", netId); 299 return -EINVAL; 300 } 301 if (int ret = static_cast<VirtualNetwork*>(network)->removeUsers(uidRanges)) { 302 return ret; 303 } 304 return 0; 305} 306 307int NetworkController::addRoute(unsigned netId, const char* interface, const char* destination, 308 const char* nexthop, bool legacy, uid_t uid) { 309 return modifyRoute(netId, interface, destination, nexthop, true, legacy, uid); 310} 311 312int NetworkController::removeRoute(unsigned netId, const char* interface, const char* destination, 313 const char* nexthop, bool legacy, uid_t uid) { 314 return modifyRoute(netId, interface, destination, nexthop, false, legacy, uid); 315} 316 317bool NetworkController::canProtect(uid_t uid) const { 318 android::RWLock::AutoRLock lock(mRWLock); 319 return ((getPermissionForUserLocked(uid) & PERMISSION_SYSTEM) == PERMISSION_SYSTEM) || 320 mProtectableUsers.find(uid) != mProtectableUsers.end(); 321} 322 323void NetworkController::allowProtect(const std::vector<uid_t>& uids) { 324 android::RWLock::AutoWLock lock(mRWLock); 325 mProtectableUsers.insert(uids.begin(), uids.end()); 326} 327 328void NetworkController::denyProtect(const std::vector<uid_t>& uids) { 329 android::RWLock::AutoWLock lock(mRWLock); 330 for (uid_t uid : uids) { 331 mProtectableUsers.erase(uid); 332 } 333} 334 335bool NetworkController::isValidNetwork(unsigned netId) const { 336 android::RWLock::AutoRLock lock(mRWLock); 337 return getNetworkLocked(netId); 338} 339 340Network* NetworkController::getNetworkLocked(unsigned netId) const { 341 auto iter = mNetworks.find(netId); 342 return iter == mNetworks.end() ? NULL : iter->second; 343} 344 345VirtualNetwork* NetworkController::getVirtualNetworkForUserLocked(uid_t uid) const { 346 for (const auto& entry : mNetworks) { 347 if (entry.second->getType() == Network::VIRTUAL) { 348 VirtualNetwork* virtualNetwork = static_cast<VirtualNetwork*>(entry.second); 349 if (virtualNetwork->appliesToUser(uid)) { 350 return virtualNetwork; 351 } 352 } 353 } 354 return NULL; 355} 356 357Permission NetworkController::getPermissionForUserLocked(uid_t uid) const { 358 auto iter = mUsers.find(uid); 359 if (iter != mUsers.end()) { 360 return iter->second; 361 } 362 return uid < FIRST_APPLICATION_UID ? PERMISSION_SYSTEM : PERMISSION_NONE; 363} 364 365int NetworkController::modifyRoute(unsigned netId, const char* interface, const char* destination, 366 const char* nexthop, bool add, bool legacy, uid_t uid) { 367 unsigned existingNetId = getNetworkForInterface(interface); 368 if (netId == NETID_UNSET || existingNetId != netId) { 369 ALOGE("interface %s assigned to netId %u, not %u", interface, existingNetId, netId); 370 return -ENOENT; 371 } 372 373 RouteController::TableType tableType; 374 if (legacy) { 375 if ((getPermissionForUser(uid) & PERMISSION_SYSTEM) == PERMISSION_SYSTEM) { 376 tableType = RouteController::LEGACY_SYSTEM; 377 } else { 378 tableType = RouteController::LEGACY_NETWORK; 379 } 380 } else { 381 tableType = RouteController::INTERFACE; 382 } 383 384 return add ? RouteController::addRoute(interface, destination, nexthop, tableType) : 385 RouteController::removeRoute(interface, destination, nexthop, tableType); 386} 387