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