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 "Fwmark.h"
36#include "LocalNetwork.h"
37#include "PhysicalNetwork.h"
38#include "RouteController.h"
39#include "VirtualNetwork.h"
40
41#include "cutils/misc.h"
42#define LOG_TAG "Netd"
43#include "log/log.h"
44#include "resolv_netid.h"
45
46namespace {
47
48// Keep these in sync with ConnectivityService.java.
49const unsigned MIN_NET_ID = 100;
50const unsigned MAX_NET_ID = 65535;
51
52}  // namespace
53
54const unsigned NetworkController::MIN_OEM_ID   =  1;
55const unsigned NetworkController::MAX_OEM_ID   = 50;
56// NetIds 51..98 are reserved for future use.
57const unsigned NetworkController::LOCAL_NET_ID = 99;
58
59// All calls to methods here are made while holding a write lock on mRWLock.
60class NetworkController::DelegateImpl : public PhysicalNetwork::Delegate {
61public:
62    explicit DelegateImpl(NetworkController* networkController);
63    virtual ~DelegateImpl();
64
65    int modifyFallthrough(unsigned vpnNetId, const std::string& physicalInterface,
66                          Permission permission, bool add) WARN_UNUSED_RESULT;
67
68private:
69    int addFallthrough(const std::string& physicalInterface,
70                       Permission permission) override WARN_UNUSED_RESULT;
71    int removeFallthrough(const std::string& physicalInterface,
72                          Permission permission) override WARN_UNUSED_RESULT;
73
74    int modifyFallthrough(const std::string& physicalInterface, Permission permission,
75                          bool add) WARN_UNUSED_RESULT;
76
77    NetworkController* const mNetworkController;
78};
79
80NetworkController::DelegateImpl::DelegateImpl(NetworkController* networkController) :
81        mNetworkController(networkController) {
82}
83
84NetworkController::DelegateImpl::~DelegateImpl() {
85}
86
87int NetworkController::DelegateImpl::modifyFallthrough(unsigned vpnNetId,
88                                                       const std::string& physicalInterface,
89                                                       Permission permission, bool add) {
90    if (add) {
91        if (int ret = RouteController::addVirtualNetworkFallthrough(vpnNetId,
92                                                                    physicalInterface.c_str(),
93                                                                    permission)) {
94            ALOGE("failed to add fallthrough to %s for VPN netId %u", physicalInterface.c_str(),
95                  vpnNetId);
96            return ret;
97        }
98    } else {
99        if (int ret = RouteController::removeVirtualNetworkFallthrough(vpnNetId,
100                                                                       physicalInterface.c_str(),
101                                                                       permission)) {
102            ALOGE("failed to remove fallthrough to %s for VPN netId %u", physicalInterface.c_str(),
103                  vpnNetId);
104            return ret;
105        }
106    }
107    return 0;
108}
109
110int NetworkController::DelegateImpl::addFallthrough(const std::string& physicalInterface,
111                                                    Permission permission) {
112    return modifyFallthrough(physicalInterface, permission, true);
113}
114
115int NetworkController::DelegateImpl::removeFallthrough(const std::string& physicalInterface,
116                                                       Permission permission) {
117    return modifyFallthrough(physicalInterface, permission, false);
118}
119
120int NetworkController::DelegateImpl::modifyFallthrough(const std::string& physicalInterface,
121                                                       Permission permission, bool add) {
122    for (const auto& entry : mNetworkController->mNetworks) {
123        if (entry.second->getType() == Network::VIRTUAL) {
124            if (int ret = modifyFallthrough(entry.first, physicalInterface, permission, add)) {
125                return ret;
126            }
127        }
128    }
129    return 0;
130}
131
132NetworkController::NetworkController() :
133        mDelegateImpl(new NetworkController::DelegateImpl(this)), mDefaultNetId(NETID_UNSET) {
134    mNetworks[LOCAL_NET_ID] = new LocalNetwork(LOCAL_NET_ID);
135}
136
137unsigned NetworkController::getDefaultNetwork() const {
138    android::RWLock::AutoRLock lock(mRWLock);
139    return mDefaultNetId;
140}
141
142int NetworkController::setDefaultNetwork(unsigned netId) {
143    android::RWLock::AutoWLock lock(mRWLock);
144
145    if (netId == mDefaultNetId) {
146        return 0;
147    }
148
149    if (netId != NETID_UNSET) {
150        Network* network = getNetworkLocked(netId);
151        if (!network) {
152            ALOGE("no such netId %u", netId);
153            return -ENONET;
154        }
155        if (network->getType() != Network::PHYSICAL) {
156            ALOGE("cannot set default to non-physical network with netId %u", netId);
157            return -EINVAL;
158        }
159        if (int ret = static_cast<PhysicalNetwork*>(network)->addAsDefault()) {
160            return ret;
161        }
162    }
163
164    if (mDefaultNetId != NETID_UNSET) {
165        Network* network = getNetworkLocked(mDefaultNetId);
166        if (!network || network->getType() != Network::PHYSICAL) {
167            ALOGE("cannot find previously set default network with netId %u", mDefaultNetId);
168            return -ESRCH;
169        }
170        if (int ret = static_cast<PhysicalNetwork*>(network)->removeAsDefault()) {
171            return ret;
172        }
173    }
174
175    mDefaultNetId = netId;
176    return 0;
177}
178
179uint32_t NetworkController::getNetworkForDns(unsigned* netId, uid_t uid) const {
180    android::RWLock::AutoRLock lock(mRWLock);
181    Fwmark fwmark;
182    fwmark.protectedFromVpn = true;
183    fwmark.permission = PERMISSION_SYSTEM;
184    if (checkUserNetworkAccessLocked(uid, *netId) == 0) {
185        // If a non-zero NetId was explicitly specified, and the user has permission for that
186        // network, use that network's DNS servers. Do not fall through to the default network even
187        // if the explicitly selected network is a split tunnel VPN or a VPN without DNS servers.
188        fwmark.explicitlySelected = true;
189    } else {
190        // If the user is subject to a VPN and the VPN provides DNS servers, use those servers
191        // (possibly falling through to the default network if the VPN doesn't provide a route to
192        // them). Otherwise, use the default network's DNS servers.
193        VirtualNetwork* virtualNetwork = getVirtualNetworkForUserLocked(uid);
194        if (virtualNetwork && virtualNetwork->getHasDns()) {
195            *netId = virtualNetwork->getNetId();
196        } else {
197            *netId = mDefaultNetId;
198        }
199    }
200    fwmark.netId = *netId;
201    return fwmark.intValue;
202}
203
204// Returns the NetId that a given UID would use if no network is explicitly selected. Specifically,
205// the VPN that applies to the UID if any; otherwise, the default network.
206unsigned NetworkController::getNetworkForUser(uid_t uid) const {
207    android::RWLock::AutoRLock lock(mRWLock);
208    if (VirtualNetwork* virtualNetwork = getVirtualNetworkForUserLocked(uid)) {
209        return virtualNetwork->getNetId();
210    }
211    return mDefaultNetId;
212}
213
214// Returns the NetId that will be set when a socket connect()s. This is the bypassable VPN that
215// applies to the user if any; otherwise, the default network.
216//
217// In general, we prefer to always set the default network's NetId in connect(), so that if the VPN
218// is a split-tunnel and disappears later, the socket continues working (since the default network's
219// NetId is still valid). Secure VPNs will correctly grab the socket's traffic since they have a
220// high-priority routing rule that doesn't care what NetId the socket has.
221//
222// But bypassable VPNs have a very low priority rule, so we need to mark the socket with the
223// bypassable VPN's NetId if we expect it to get any traffic at all. If the bypassable VPN is a
224// split-tunnel, that's okay, because we have fallthrough rules that will direct the fallthrough
225// traffic to the default network. But it does mean that if the bypassable VPN goes away (and thus
226// the fallthrough rules also go away), the socket that used to fallthrough to the default network
227// will stop working.
228unsigned NetworkController::getNetworkForConnect(uid_t uid) const {
229    android::RWLock::AutoRLock lock(mRWLock);
230    VirtualNetwork* virtualNetwork = getVirtualNetworkForUserLocked(uid);
231    if (virtualNetwork && !virtualNetwork->isSecure()) {
232        return virtualNetwork->getNetId();
233    }
234    return mDefaultNetId;
235}
236
237unsigned NetworkController::getNetworkForInterface(const char* interface) const {
238    android::RWLock::AutoRLock lock(mRWLock);
239    for (const auto& entry : mNetworks) {
240        if (entry.second->hasInterface(interface)) {
241            return entry.first;
242        }
243    }
244    return NETID_UNSET;
245}
246
247bool NetworkController::isVirtualNetwork(unsigned netId) const {
248    android::RWLock::AutoRLock lock(mRWLock);
249    Network* network = getNetworkLocked(netId);
250    return network && network->getType() == Network::VIRTUAL;
251}
252
253int NetworkController::createPhysicalNetwork(unsigned netId, Permission permission) {
254    if (!((MIN_NET_ID <= netId && netId <= MAX_NET_ID) ||
255          (MIN_OEM_ID <= netId && netId <= MAX_OEM_ID))) {
256        ALOGE("invalid netId %u", netId);
257        return -EINVAL;
258    }
259
260    if (isValidNetwork(netId)) {
261        ALOGE("duplicate netId %u", netId);
262        return -EEXIST;
263    }
264
265    PhysicalNetwork* physicalNetwork = new PhysicalNetwork(netId, mDelegateImpl);
266    if (int ret = physicalNetwork->setPermission(permission)) {
267        ALOGE("inconceivable! setPermission cannot fail on an empty network");
268        delete physicalNetwork;
269        return ret;
270    }
271
272    android::RWLock::AutoWLock lock(mRWLock);
273    mNetworks[netId] = physicalNetwork;
274    return 0;
275}
276
277int NetworkController::createVirtualNetwork(unsigned netId, bool hasDns, bool secure) {
278    if (!(MIN_NET_ID <= netId && netId <= MAX_NET_ID)) {
279        ALOGE("invalid netId %u", netId);
280        return -EINVAL;
281    }
282
283    if (isValidNetwork(netId)) {
284        ALOGE("duplicate netId %u", netId);
285        return -EEXIST;
286    }
287
288    android::RWLock::AutoWLock lock(mRWLock);
289    if (int ret = modifyFallthroughLocked(netId, true)) {
290        return ret;
291    }
292    mNetworks[netId] = new VirtualNetwork(netId, hasDns, secure);
293    return 0;
294}
295
296int NetworkController::destroyNetwork(unsigned netId) {
297    if (netId == LOCAL_NET_ID) {
298        ALOGE("cannot destroy local network");
299        return -EINVAL;
300    }
301    if (!isValidNetwork(netId)) {
302        ALOGE("no such netId %u", netId);
303        return -ENONET;
304    }
305
306    // TODO: ioctl(SIOCKILLADDR, ...) to kill all sockets on the old network.
307
308    android::RWLock::AutoWLock lock(mRWLock);
309    Network* network = getNetworkLocked(netId);
310
311    // If we fail to destroy a network, things will get stuck badly. Therefore, unlike most of the
312    // other network code, ignore failures and attempt to clear out as much state as possible, even
313    // if we hit an error on the way. Return the first error that we see.
314    int ret = network->clearInterfaces();
315
316    if (mDefaultNetId == netId) {
317        if (int err = static_cast<PhysicalNetwork*>(network)->removeAsDefault()) {
318            ALOGE("inconceivable! removeAsDefault cannot fail on an empty network");
319            if (!ret) {
320                ret = err;
321            }
322        }
323        mDefaultNetId = NETID_UNSET;
324    } else if (network->getType() == Network::VIRTUAL) {
325        if (int err = modifyFallthroughLocked(netId, false)) {
326            if (!ret) {
327                ret = err;
328            }
329        }
330    }
331    mNetworks.erase(netId);
332    delete network;
333    _resolv_delete_cache_for_net(netId);
334    return ret;
335}
336
337int NetworkController::addInterfaceToNetwork(unsigned netId, const char* interface) {
338    if (!isValidNetwork(netId)) {
339        ALOGE("no such netId %u", netId);
340        return -ENONET;
341    }
342
343    unsigned existingNetId = getNetworkForInterface(interface);
344    if (existingNetId != NETID_UNSET && existingNetId != netId) {
345        ALOGE("interface %s already assigned to netId %u", interface, existingNetId);
346        return -EBUSY;
347    }
348
349    android::RWLock::AutoWLock lock(mRWLock);
350    return getNetworkLocked(netId)->addInterface(interface);
351}
352
353int NetworkController::removeInterfaceFromNetwork(unsigned netId, const char* interface) {
354    if (!isValidNetwork(netId)) {
355        ALOGE("no such netId %u", netId);
356        return -ENONET;
357    }
358
359    android::RWLock::AutoWLock lock(mRWLock);
360    return getNetworkLocked(netId)->removeInterface(interface);
361}
362
363Permission NetworkController::getPermissionForUser(uid_t uid) const {
364    android::RWLock::AutoRLock lock(mRWLock);
365    return getPermissionForUserLocked(uid);
366}
367
368void NetworkController::setPermissionForUsers(Permission permission,
369                                              const std::vector<uid_t>& uids) {
370    android::RWLock::AutoWLock lock(mRWLock);
371    for (uid_t uid : uids) {
372        mUsers[uid] = permission;
373    }
374}
375
376int NetworkController::checkUserNetworkAccess(uid_t uid, unsigned netId) const {
377    android::RWLock::AutoRLock lock(mRWLock);
378    return checkUserNetworkAccessLocked(uid, netId);
379}
380
381int NetworkController::setPermissionForNetworks(Permission permission,
382                                                const std::vector<unsigned>& netIds) {
383    android::RWLock::AutoWLock lock(mRWLock);
384    for (unsigned netId : netIds) {
385        Network* network = getNetworkLocked(netId);
386        if (!network) {
387            ALOGE("no such netId %u", netId);
388            return -ENONET;
389        }
390        if (network->getType() != Network::PHYSICAL) {
391            ALOGE("cannot set permissions on non-physical network with netId %u", netId);
392            return -EINVAL;
393        }
394
395        // TODO: ioctl(SIOCKILLADDR, ...) to kill socets on the network that don't have permission.
396
397        if (int ret = static_cast<PhysicalNetwork*>(network)->setPermission(permission)) {
398            return ret;
399        }
400    }
401    return 0;
402}
403
404int NetworkController::addUsersToNetwork(unsigned netId, const UidRanges& uidRanges) {
405    android::RWLock::AutoWLock lock(mRWLock);
406    Network* network = getNetworkLocked(netId);
407    if (!network) {
408        ALOGE("no such netId %u", netId);
409        return -ENONET;
410    }
411    if (network->getType() != Network::VIRTUAL) {
412        ALOGE("cannot add users to non-virtual network with netId %u", netId);
413        return -EINVAL;
414    }
415    if (int ret = static_cast<VirtualNetwork*>(network)->addUsers(uidRanges)) {
416        return ret;
417    }
418    return 0;
419}
420
421int NetworkController::removeUsersFromNetwork(unsigned netId, const UidRanges& uidRanges) {
422    android::RWLock::AutoWLock lock(mRWLock);
423    Network* network = getNetworkLocked(netId);
424    if (!network) {
425        ALOGE("no such netId %u", netId);
426        return -ENONET;
427    }
428    if (network->getType() != Network::VIRTUAL) {
429        ALOGE("cannot remove users from non-virtual network with netId %u", netId);
430        return -EINVAL;
431    }
432    if (int ret = static_cast<VirtualNetwork*>(network)->removeUsers(uidRanges)) {
433        return ret;
434    }
435    return 0;
436}
437
438int NetworkController::addRoute(unsigned netId, const char* interface, const char* destination,
439                                const char* nexthop, bool legacy, uid_t uid) {
440    return modifyRoute(netId, interface, destination, nexthop, true, legacy, uid);
441}
442
443int NetworkController::removeRoute(unsigned netId, const char* interface, const char* destination,
444                                   const char* nexthop, bool legacy, uid_t uid) {
445    return modifyRoute(netId, interface, destination, nexthop, false, legacy, uid);
446}
447
448bool NetworkController::canProtect(uid_t uid) const {
449    android::RWLock::AutoRLock lock(mRWLock);
450    return ((getPermissionForUserLocked(uid) & PERMISSION_SYSTEM) == PERMISSION_SYSTEM) ||
451           mProtectableUsers.find(uid) != mProtectableUsers.end();
452}
453
454void NetworkController::allowProtect(const std::vector<uid_t>& uids) {
455    android::RWLock::AutoWLock lock(mRWLock);
456    mProtectableUsers.insert(uids.begin(), uids.end());
457}
458
459void NetworkController::denyProtect(const std::vector<uid_t>& uids) {
460    android::RWLock::AutoWLock lock(mRWLock);
461    for (uid_t uid : uids) {
462        mProtectableUsers.erase(uid);
463    }
464}
465
466bool NetworkController::isValidNetwork(unsigned netId) const {
467    android::RWLock::AutoRLock lock(mRWLock);
468    return getNetworkLocked(netId);
469}
470
471Network* NetworkController::getNetworkLocked(unsigned netId) const {
472    auto iter = mNetworks.find(netId);
473    return iter == mNetworks.end() ? NULL : iter->second;
474}
475
476VirtualNetwork* NetworkController::getVirtualNetworkForUserLocked(uid_t uid) const {
477    for (const auto& entry : mNetworks) {
478        if (entry.second->getType() == Network::VIRTUAL) {
479            VirtualNetwork* virtualNetwork = static_cast<VirtualNetwork*>(entry.second);
480            if (virtualNetwork->appliesToUser(uid)) {
481                return virtualNetwork;
482            }
483        }
484    }
485    return NULL;
486}
487
488Permission NetworkController::getPermissionForUserLocked(uid_t uid) const {
489    auto iter = mUsers.find(uid);
490    if (iter != mUsers.end()) {
491        return iter->second;
492    }
493    return uid < FIRST_APPLICATION_UID ? PERMISSION_SYSTEM : PERMISSION_NONE;
494}
495
496int NetworkController::checkUserNetworkAccessLocked(uid_t uid, unsigned netId) const {
497    Network* network = getNetworkLocked(netId);
498    if (!network) {
499        return -ENONET;
500    }
501
502    // If uid is INVALID_UID, this likely means that we were unable to retrieve the UID of the peer
503    // (using SO_PEERCRED). Be safe and deny access to the network, even if it's valid.
504    if (uid == INVALID_UID) {
505        return -EREMOTEIO;
506    }
507    Permission userPermission = getPermissionForUserLocked(uid);
508    if ((userPermission & PERMISSION_SYSTEM) == PERMISSION_SYSTEM) {
509        return 0;
510    }
511    if (network->getType() == Network::VIRTUAL) {
512        return static_cast<VirtualNetwork*>(network)->appliesToUser(uid) ? 0 : -EPERM;
513    }
514    VirtualNetwork* virtualNetwork = getVirtualNetworkForUserLocked(uid);
515    if (virtualNetwork && virtualNetwork->isSecure() &&
516            mProtectableUsers.find(uid) == mProtectableUsers.end()) {
517        return -EPERM;
518    }
519    Permission networkPermission = static_cast<PhysicalNetwork*>(network)->getPermission();
520    return ((userPermission & networkPermission) == networkPermission) ? 0 : -EACCES;
521}
522
523int NetworkController::modifyRoute(unsigned netId, const char* interface, const char* destination,
524                                   const char* nexthop, bool add, bool legacy, uid_t uid) {
525    if (!isValidNetwork(netId)) {
526        ALOGE("no such netId %u", netId);
527        return -ENONET;
528    }
529    unsigned existingNetId = getNetworkForInterface(interface);
530    if (existingNetId == NETID_UNSET) {
531        ALOGE("interface %s not assigned to any netId", interface);
532        return -ENODEV;
533    }
534    if (existingNetId != netId) {
535        ALOGE("interface %s assigned to netId %u, not %u", interface, existingNetId, netId);
536        return -ENOENT;
537    }
538
539    RouteController::TableType tableType;
540    if (netId == LOCAL_NET_ID) {
541        tableType = RouteController::LOCAL_NETWORK;
542    } else if (legacy) {
543        if ((getPermissionForUser(uid) & PERMISSION_SYSTEM) == PERMISSION_SYSTEM) {
544            tableType = RouteController::LEGACY_SYSTEM;
545        } else {
546            tableType = RouteController::LEGACY_NETWORK;
547        }
548    } else {
549        tableType = RouteController::INTERFACE;
550    }
551
552    return add ? RouteController::addRoute(interface, destination, nexthop, tableType) :
553                 RouteController::removeRoute(interface, destination, nexthop, tableType);
554}
555
556int NetworkController::modifyFallthroughLocked(unsigned vpnNetId, bool add) {
557    if (mDefaultNetId == NETID_UNSET) {
558        return 0;
559    }
560    Network* network = getNetworkLocked(mDefaultNetId);
561    if (!network) {
562        ALOGE("cannot find previously set default network with netId %u", mDefaultNetId);
563        return -ESRCH;
564    }
565    if (network->getType() != Network::PHYSICAL) {
566        ALOGE("inconceivable! default network must be a physical network");
567        return -EINVAL;
568    }
569    Permission permission = static_cast<PhysicalNetwork*>(network)->getPermission();
570    for (const auto& physicalInterface : network->getInterfaces()) {
571        if (int ret = mDelegateImpl->modifyFallthrough(vpnNetId, physicalInterface, permission,
572                                                       add)) {
573            return ret;
574        }
575    }
576    return 0;
577}
578