OSDN Git Service

Implement the fallthrough rule to support split tunnel VPNs.
[android-x86/system-netd.git] / server / NetworkController.cpp
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
45 namespace {
46
47 // Keep these in sync with ConnectivityService.java.
48 const unsigned MIN_NET_ID = 10;
49 const unsigned MAX_NET_ID = 65535;
50
51 }  // namespace
52
53 // All calls to methods here are made while holding a write lock on mRWLock.
54 class NetworkController::DelegateImpl : public PhysicalNetwork::Delegate {
55 public:
56     explicit DelegateImpl(NetworkController* networkController);
57     virtual ~DelegateImpl();
58
59     int modifyFallthrough(unsigned vpnNetId, const std::string& physicalInterface,
60                           Permission permission, bool add) WARN_UNUSED_RESULT;
61
62 private:
63     int addFallthrough(const std::string& physicalInterface,
64                        Permission permission) override WARN_UNUSED_RESULT;
65     int removeFallthrough(const std::string& physicalInterface,
66                           Permission permission) override WARN_UNUSED_RESULT;
67
68     int modifyFallthrough(const std::string& physicalInterface, Permission permission,
69                           bool add) WARN_UNUSED_RESULT;
70
71     NetworkController* const mNetworkController;
72 };
73
74 NetworkController::DelegateImpl::DelegateImpl(NetworkController* networkController) :
75         mNetworkController(networkController) {
76 }
77
78 NetworkController::DelegateImpl::~DelegateImpl() {
79 }
80
81 int NetworkController::DelegateImpl::modifyFallthrough(unsigned vpnNetId,
82                                                        const std::string& physicalInterface,
83                                                        Permission permission, bool add) {
84     if (add) {
85         if (int ret = RouteController::addVirtualNetworkFallthrough(vpnNetId,
86                                                                     physicalInterface.c_str(),
87                                                                     permission)) {
88             ALOGE("failed to add fallthrough to %s for VPN netId %u", physicalInterface.c_str(),
89                   vpnNetId);
90             return ret;
91         }
92     } else {
93         if (int ret = RouteController::removeVirtualNetworkFallthrough(vpnNetId,
94                                                                        physicalInterface.c_str(),
95                                                                        permission)) {
96             ALOGE("failed to remove fallthrough to %s for VPN netId %u", physicalInterface.c_str(),
97                   vpnNetId);
98             return ret;
99         }
100     }
101     return 0;
102 }
103
104 int NetworkController::DelegateImpl::addFallthrough(const std::string& physicalInterface,
105                                                     Permission permission) {
106     return modifyFallthrough(physicalInterface, permission, true);
107 }
108
109 int NetworkController::DelegateImpl::removeFallthrough(const std::string& physicalInterface,
110                                                        Permission permission) {
111     return modifyFallthrough(physicalInterface, permission, false);
112 }
113
114 int NetworkController::DelegateImpl::modifyFallthrough(const std::string& physicalInterface,
115                                                        Permission permission, bool add) {
116     for (const auto& entry : mNetworkController->mNetworks) {
117         if (entry.second->getType() == Network::VIRTUAL) {
118             if (int ret = modifyFallthrough(entry.first, physicalInterface, permission, add)) {
119                 return ret;
120             }
121         }
122     }
123     return 0;
124 }
125
126 NetworkController::NetworkController() :
127         mDelegateImpl(new NetworkController::DelegateImpl(this)), mDefaultNetId(NETID_UNSET) {
128     mNetworks[LOCAL_NET_ID] = new LocalNetwork(LOCAL_NET_ID);
129 }
130
131 unsigned NetworkController::getDefaultNetwork() const {
132     android::RWLock::AutoRLock lock(mRWLock);
133     return mDefaultNetId;
134 }
135
136 int NetworkController::setDefaultNetwork(unsigned netId) {
137     android::RWLock::AutoWLock lock(mRWLock);
138
139     if (netId == mDefaultNetId) {
140         return 0;
141     }
142
143     if (netId != NETID_UNSET) {
144         Network* network = getNetworkLocked(netId);
145         if (!network || network->getType() != Network::PHYSICAL) {
146             ALOGE("invalid netId %u", netId);
147             return -EINVAL;
148         }
149         if (int ret = static_cast<PhysicalNetwork*>(network)->addAsDefault()) {
150             return ret;
151         }
152     }
153
154     if (mDefaultNetId != NETID_UNSET) {
155         Network* network = getNetworkLocked(mDefaultNetId);
156         if (!network || network->getType() != Network::PHYSICAL) {
157             ALOGE("cannot find previously set default network with netId %u", mDefaultNetId);
158             return -ESRCH;
159         }
160         if (int ret = static_cast<PhysicalNetwork*>(network)->removeAsDefault()) {
161             return ret;
162         }
163     }
164
165     mDefaultNetId = netId;
166     return 0;
167 }
168
169 unsigned NetworkController::getNetworkForUser(uid_t uid, unsigned requestedNetId,
170                                               bool forDns) const {
171     android::RWLock::AutoRLock lock(mRWLock);
172     VirtualNetwork* virtualNetwork = getVirtualNetworkForUserLocked(uid);
173     if (virtualNetwork && (!forDns || virtualNetwork->getHasDns())) {
174         return virtualNetwork->getNetId();
175     }
176     return getNetworkLocked(requestedNetId) ? requestedNetId : mDefaultNetId;
177 }
178
179 unsigned NetworkController::getNetworkForInterface(const char* interface) const {
180     android::RWLock::AutoRLock lock(mRWLock);
181     for (const auto& entry : mNetworks) {
182         if (entry.second->hasInterface(interface)) {
183             return entry.first;
184         }
185     }
186     return NETID_UNSET;
187 }
188
189 bool NetworkController::isVirtualNetwork(unsigned netId) const {
190     android::RWLock::AutoRLock lock(mRWLock);
191     Network* network = getNetworkLocked(netId);
192     return network && network->getType() == Network::VIRTUAL;
193 }
194
195 int NetworkController::createPhysicalNetwork(unsigned netId, Permission permission) {
196     if (netId < MIN_NET_ID || netId > MAX_NET_ID) {
197         ALOGE("invalid netId %u", netId);
198         return -EINVAL;
199     }
200
201     if (isValidNetwork(netId)) {
202         ALOGE("duplicate netId %u", netId);
203         return -EEXIST;
204     }
205
206     PhysicalNetwork* physicalNetwork = new PhysicalNetwork(netId, mDelegateImpl);
207     if (int ret = physicalNetwork->setPermission(permission)) {
208         ALOGE("inconceivable! setPermission cannot fail on an empty network");
209         delete physicalNetwork;
210         return ret;
211     }
212
213     android::RWLock::AutoWLock lock(mRWLock);
214     mNetworks[netId] = physicalNetwork;
215     return 0;
216 }
217
218 int NetworkController::createVirtualNetwork(unsigned netId, bool hasDns, bool secure) {
219     if (netId < MIN_NET_ID || netId > MAX_NET_ID) {
220         ALOGE("invalid netId %u", netId);
221         return -EINVAL;
222     }
223
224     if (isValidNetwork(netId)) {
225         ALOGE("duplicate netId %u", netId);
226         return -EEXIST;
227     }
228
229     android::RWLock::AutoWLock lock(mRWLock);
230     if (int ret = modifyFallthroughLocked(netId, true)) {
231         return ret;
232     }
233     mNetworks[netId] = new VirtualNetwork(netId, hasDns, secure);
234     return 0;
235 }
236
237 int NetworkController::destroyNetwork(unsigned netId) {
238     if (netId == LOCAL_NET_ID || !isValidNetwork(netId)) {
239         ALOGE("invalid netId %u", netId);
240         return -EINVAL;
241     }
242
243     // TODO: ioctl(SIOCKILLADDR, ...) to kill all sockets on the old network.
244
245     android::RWLock::AutoWLock lock(mRWLock);
246     Network* network = getNetworkLocked(netId);
247     if (int ret = network->clearInterfaces()) {
248         return ret;
249     }
250     if (mDefaultNetId == netId) {
251         if (int ret = static_cast<PhysicalNetwork*>(network)->removeAsDefault()) {
252             ALOGE("inconceivable! removeAsDefault cannot fail on an empty network");
253             return ret;
254         }
255         mDefaultNetId = NETID_UNSET;
256     } else if (network->getType() == Network::VIRTUAL) {
257         if (int ret = modifyFallthroughLocked(netId, false)) {
258             return ret;
259         }
260     }
261     mNetworks.erase(netId);
262     delete network;
263     _resolv_delete_cache_for_net(netId);
264     return 0;
265 }
266
267 int NetworkController::addInterfaceToNetwork(unsigned netId, const char* interface) {
268     if (!isValidNetwork(netId)) {
269         ALOGE("invalid netId %u", netId);
270         return -EINVAL;
271     }
272
273     unsigned existingNetId = getNetworkForInterface(interface);
274     if (existingNetId != NETID_UNSET && existingNetId != netId) {
275         ALOGE("interface %s already assigned to netId %u", interface, existingNetId);
276         return -EBUSY;
277     }
278
279     android::RWLock::AutoWLock lock(mRWLock);
280     return getNetworkLocked(netId)->addInterface(interface);
281 }
282
283 int NetworkController::removeInterfaceFromNetwork(unsigned netId, const char* interface) {
284     if (!isValidNetwork(netId)) {
285         ALOGE("invalid netId %u", netId);
286         return -EINVAL;
287     }
288
289     android::RWLock::AutoWLock lock(mRWLock);
290     return getNetworkLocked(netId)->removeInterface(interface);
291 }
292
293 Permission NetworkController::getPermissionForUser(uid_t uid) const {
294     android::RWLock::AutoRLock lock(mRWLock);
295     return getPermissionForUserLocked(uid);
296 }
297
298 void NetworkController::setPermissionForUsers(Permission permission,
299                                               const std::vector<uid_t>& uids) {
300     android::RWLock::AutoWLock lock(mRWLock);
301     for (uid_t uid : uids) {
302         mUsers[uid] = permission;
303     }
304 }
305
306 bool NetworkController::canUserSelectNetwork(uid_t uid, unsigned netId) const {
307     android::RWLock::AutoRLock lock(mRWLock);
308     Network* network = getNetworkLocked(netId);
309     if (!network || uid == INVALID_UID) {
310         return false;
311     }
312     Permission userPermission = getPermissionForUserLocked(uid);
313     if ((userPermission & PERMISSION_SYSTEM) == PERMISSION_SYSTEM) {
314         return true;
315     }
316     if (network->getType() == Network::VIRTUAL) {
317         return static_cast<VirtualNetwork*>(network)->appliesToUser(uid);
318     }
319     VirtualNetwork* virtualNetwork = getVirtualNetworkForUserLocked(uid);
320     if (virtualNetwork && virtualNetwork->isSecure() &&
321             mProtectableUsers.find(uid) == mProtectableUsers.end()) {
322         return false;
323     }
324     Permission networkPermission = static_cast<PhysicalNetwork*>(network)->getPermission();
325     return (userPermission & networkPermission) == networkPermission;
326 }
327
328 int NetworkController::setPermissionForNetworks(Permission permission,
329                                                 const std::vector<unsigned>& netIds) {
330     android::RWLock::AutoWLock lock(mRWLock);
331     for (unsigned netId : netIds) {
332         Network* network = getNetworkLocked(netId);
333         if (!network || network->getType() != Network::PHYSICAL) {
334             ALOGE("invalid netId %u", netId);
335             return -EINVAL;
336         }
337
338         // TODO: ioctl(SIOCKILLADDR, ...) to kill socets on the network that don't have permission.
339
340         if (int ret = static_cast<PhysicalNetwork*>(network)->setPermission(permission)) {
341             return ret;
342         }
343     }
344     return 0;
345 }
346
347 int NetworkController::addUsersToNetwork(unsigned netId, const UidRanges& uidRanges) {
348     android::RWLock::AutoWLock lock(mRWLock);
349     Network* network = getNetworkLocked(netId);
350     if (!network || network->getType() != Network::VIRTUAL) {
351         ALOGE("invalid netId %u", netId);
352         return -EINVAL;
353     }
354     if (int ret = static_cast<VirtualNetwork*>(network)->addUsers(uidRanges)) {
355         return ret;
356     }
357     return 0;
358 }
359
360 int NetworkController::removeUsersFromNetwork(unsigned netId, const UidRanges& uidRanges) {
361     android::RWLock::AutoWLock lock(mRWLock);
362     Network* network = getNetworkLocked(netId);
363     if (!network || network->getType() != Network::VIRTUAL) {
364         ALOGE("invalid netId %u", netId);
365         return -EINVAL;
366     }
367     if (int ret = static_cast<VirtualNetwork*>(network)->removeUsers(uidRanges)) {
368         return ret;
369     }
370     return 0;
371 }
372
373 int NetworkController::addRoute(unsigned netId, const char* interface, const char* destination,
374                                 const char* nexthop, bool legacy, uid_t uid) {
375     return modifyRoute(netId, interface, destination, nexthop, true, legacy, uid);
376 }
377
378 int NetworkController::removeRoute(unsigned netId, const char* interface, const char* destination,
379                                    const char* nexthop, bool legacy, uid_t uid) {
380     return modifyRoute(netId, interface, destination, nexthop, false, legacy, uid);
381 }
382
383 bool NetworkController::canProtect(uid_t uid) const {
384     android::RWLock::AutoRLock lock(mRWLock);
385     return ((getPermissionForUserLocked(uid) & PERMISSION_SYSTEM) == PERMISSION_SYSTEM) ||
386            mProtectableUsers.find(uid) != mProtectableUsers.end();
387 }
388
389 void NetworkController::allowProtect(const std::vector<uid_t>& uids) {
390     android::RWLock::AutoWLock lock(mRWLock);
391     mProtectableUsers.insert(uids.begin(), uids.end());
392 }
393
394 void NetworkController::denyProtect(const std::vector<uid_t>& uids) {
395     android::RWLock::AutoWLock lock(mRWLock);
396     for (uid_t uid : uids) {
397         mProtectableUsers.erase(uid);
398     }
399 }
400
401 bool NetworkController::isValidNetwork(unsigned netId) const {
402     android::RWLock::AutoRLock lock(mRWLock);
403     return getNetworkLocked(netId);
404 }
405
406 Network* NetworkController::getNetworkLocked(unsigned netId) const {
407     auto iter = mNetworks.find(netId);
408     return iter == mNetworks.end() ? NULL : iter->second;
409 }
410
411 VirtualNetwork* NetworkController::getVirtualNetworkForUserLocked(uid_t uid) const {
412     for (const auto& entry : mNetworks) {
413         if (entry.second->getType() == Network::VIRTUAL) {
414             VirtualNetwork* virtualNetwork = static_cast<VirtualNetwork*>(entry.second);
415             if (virtualNetwork->appliesToUser(uid)) {
416                 return virtualNetwork;
417             }
418         }
419     }
420     return NULL;
421 }
422
423 Permission NetworkController::getPermissionForUserLocked(uid_t uid) const {
424     auto iter = mUsers.find(uid);
425     if (iter != mUsers.end()) {
426         return iter->second;
427     }
428     return uid < FIRST_APPLICATION_UID ? PERMISSION_SYSTEM : PERMISSION_NONE;
429 }
430
431 int NetworkController::modifyRoute(unsigned netId, const char* interface, const char* destination,
432                                    const char* nexthop, bool add, bool legacy, uid_t uid) {
433     unsigned existingNetId = getNetworkForInterface(interface);
434     if (netId == NETID_UNSET || existingNetId != netId) {
435         ALOGE("interface %s assigned to netId %u, not %u", interface, existingNetId, netId);
436         return -ENOENT;
437     }
438
439     RouteController::TableType tableType;
440     if (netId == LOCAL_NET_ID) {
441         tableType = RouteController::LOCAL_NETWORK;
442     } else if (legacy) {
443         if ((getPermissionForUser(uid) & PERMISSION_SYSTEM) == PERMISSION_SYSTEM) {
444             tableType = RouteController::LEGACY_SYSTEM;
445         } else {
446             tableType = RouteController::LEGACY_NETWORK;
447         }
448     } else {
449         tableType = RouteController::INTERFACE;
450     }
451
452     return add ? RouteController::addRoute(interface, destination, nexthop, tableType) :
453                  RouteController::removeRoute(interface, destination, nexthop, tableType);
454 }
455
456 int NetworkController::modifyFallthroughLocked(unsigned vpnNetId, bool add) {
457     if (mDefaultNetId == NETID_UNSET) {
458         return 0;
459     }
460     Network* network = getNetworkLocked(mDefaultNetId);
461     if (!network || network->getType() != Network::PHYSICAL) {
462         ALOGE("cannot find previously set default network with netId %u", mDefaultNetId);
463         return -ESRCH;
464     }
465     Permission permission = static_cast<PhysicalNetwork*>(network)->getPermission();
466     for (const auto& physicalInterface : network->getInterfaces()) {
467         if (int ret = mDelegateImpl->modifyFallthrough(vpnNetId, physicalInterface, permission,
468                                                        add)) {
469             return ret;
470         }
471     }
472     return 0;
473 }