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