NetworkController.cpp revision 36ed53e37b2639681055b2d3d8777241e7dd6982
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, uid_t ownerUid) {
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, ownerUid);
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
334Network* NetworkController::getNetworkLocked(unsigned netId) const {
335    auto iter = mNetworks.find(netId);
336    return iter == mNetworks.end() ? NULL : iter->second;
337}
338
339int NetworkController::modifyRoute(unsigned netId, const char* interface, const char* destination,
340                                   const char* nexthop, bool add, bool legacy, uid_t uid) {
341    unsigned existingNetId = getNetworkId(interface);
342    if (netId == NETID_UNSET || existingNetId != netId) {
343        ALOGE("interface %s assigned to netId %u, not %u", interface, existingNetId, netId);
344        return -ENOENT;
345    }
346
347    RouteController::TableType tableType;
348    if (legacy) {
349        if (getPermissionForUser(uid) & PERMISSION_CONNECTIVITY_INTERNAL) {
350            tableType = RouteController::PRIVILEGED_LEGACY;
351        } else {
352            tableType = RouteController::LEGACY;
353        }
354    } else {
355        tableType = RouteController::INTERFACE;
356    }
357
358    return add ? RouteController::addRoute(interface, destination, nexthop, tableType) :
359                 RouteController::removeRoute(interface, destination, nexthop, tableType);
360}
361
362NetworkController::UidEntry::UidEntry(uid_t uidStart, uid_t uidEnd, unsigned netId,
363                                      bool forwardDns) :
364        uidStart(uidStart), uidEnd(uidEnd), netId(netId), forwardDns(forwardDns) {
365}
366