Home | History | Annotate | Download | only in server
      1 /**
      2  * Copyright (c) 2016, 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 #define LOG_TAG "Netd"
     18 
     19 #include <vector>
     20 
     21 #include <android-base/stringprintf.h>
     22 #include <cutils/log.h>
     23 #include <utils/Errors.h>
     24 #include <utils/String16.h>
     25 
     26 #include <binder/IPCThreadState.h>
     27 #include <binder/IServiceManager.h>
     28 #include "android/net/BnNetd.h"
     29 
     30 #include "Controllers.h"
     31 #include "DumpWriter.h"
     32 #include "InterfaceController.h"
     33 #include "NetdConstants.h"
     34 #include "NetdNativeService.h"
     35 #include "RouteController.h"
     36 #include "SockDiag.h"
     37 #include "UidRanges.h"
     38 
     39 using android::base::StringPrintf;
     40 
     41 namespace android {
     42 namespace net {
     43 
     44 namespace {
     45 
     46 const char CONNECTIVITY_INTERNAL[] = "android.permission.CONNECTIVITY_INTERNAL";
     47 const char DUMP[] = "android.permission.DUMP";
     48 
     49 binder::Status checkPermission(const char *permission) {
     50     pid_t pid;
     51     uid_t uid;
     52 
     53     if (checkCallingPermission(String16(permission), (int32_t *) &pid, (int32_t *) &uid)) {
     54         return binder::Status::ok();
     55     } else {
     56         auto err = StringPrintf("UID %d / PID %d lacks permission %s", uid, pid, permission);
     57         return binder::Status::fromExceptionCode(binder::Status::EX_SECURITY, String8(err.c_str()));
     58     }
     59 }
     60 
     61 #define ENFORCE_PERMISSION(permission) {                    \
     62     binder::Status status = checkPermission((permission));  \
     63     if (!status.isOk()) {                                   \
     64         return status;                                      \
     65     }                                                       \
     66 }
     67 
     68 #define NETD_LOCKING_RPC(permission, lock)                  \
     69     ENFORCE_PERMISSION(permission);                         \
     70     android::RWLock::AutoWLock _lock(lock);
     71 
     72 #define NETD_BIG_LOCK_RPC(permission) NETD_LOCKING_RPC((permission), gBigNetdLock)
     73 }  // namespace
     74 
     75 
     76 status_t NetdNativeService::start() {
     77     IPCThreadState::self()->disableBackgroundScheduling(true);
     78     status_t ret = BinderService<NetdNativeService>::publish();
     79     if (ret != android::OK) {
     80         return ret;
     81     }
     82     sp<ProcessState> ps(ProcessState::self());
     83     ps->startThreadPool();
     84     ps->giveThreadPoolName();
     85     return android::OK;
     86 }
     87 
     88 status_t NetdNativeService::dump(int fd, const Vector<String16> & /* args */) {
     89     const binder::Status dump_permission = checkPermission(DUMP);
     90     if (!dump_permission.isOk()) {
     91         const String8 msg(dump_permission.toString8());
     92         write(fd, msg.string(), msg.size());
     93         return PERMISSION_DENIED;
     94     }
     95 
     96     // This method does not grab any locks. If individual classes need locking
     97     // their dump() methods MUST handle locking appropriately.
     98     DumpWriter dw(fd);
     99     dw.blankline();
    100     gCtls->netCtrl.dump(dw);
    101     dw.blankline();
    102 
    103     return NO_ERROR;
    104 }
    105 
    106 binder::Status NetdNativeService::isAlive(bool *alive) {
    107     NETD_BIG_LOCK_RPC(CONNECTIVITY_INTERNAL);
    108 
    109     *alive = true;
    110     return binder::Status::ok();
    111 }
    112 
    113 binder::Status NetdNativeService::firewallReplaceUidChain(const android::String16& chainName,
    114         bool isWhitelist, const std::vector<int32_t>& uids, bool *ret) {
    115     NETD_LOCKING_RPC(CONNECTIVITY_INTERNAL, gCtls->firewallCtrl.lock);
    116 
    117     android::String8 name = android::String8(chainName);
    118     int err = gCtls->firewallCtrl.replaceUidChain(name.string(), isWhitelist, uids);
    119     *ret = (err == 0);
    120     return binder::Status::ok();
    121 }
    122 
    123 binder::Status NetdNativeService::bandwidthEnableDataSaver(bool enable, bool *ret) {
    124     NETD_LOCKING_RPC(CONNECTIVITY_INTERNAL, gCtls->bandwidthCtrl.lock);
    125 
    126     int err = gCtls->bandwidthCtrl.enableDataSaver(enable);
    127     *ret = (err == 0);
    128     return binder::Status::ok();
    129 }
    130 
    131 binder::Status NetdNativeService::networkRejectNonSecureVpn(bool add,
    132         const std::vector<UidRange>& uidRangeArray) {
    133     // TODO: elsewhere RouteController is only used from the tethering and network controllers, so
    134     // it should be possible to use the same lock as NetworkController. However, every call through
    135     // the CommandListener "network" command will need to hold this lock too, not just the ones that
    136     // read/modify network internal state (that is sufficient for ::dump() because it doesn't
    137     // look at routes, but it's not enough here).
    138     NETD_BIG_LOCK_RPC(CONNECTIVITY_INTERNAL);
    139 
    140     UidRanges uidRanges(uidRangeArray);
    141 
    142     int err;
    143     if (add) {
    144         err = RouteController::addUsersToRejectNonSecureNetworkRule(uidRanges);
    145     } else {
    146         err = RouteController::removeUsersFromRejectNonSecureNetworkRule(uidRanges);
    147     }
    148 
    149     if (err != 0) {
    150         return binder::Status::fromServiceSpecificError(-err,
    151                 String8::format("RouteController error: %s", strerror(-err)));
    152     }
    153     return binder::Status::ok();
    154 }
    155 
    156 binder::Status NetdNativeService::socketDestroy(const std::vector<UidRange>& uids,
    157         const std::vector<int32_t>& skipUids) {
    158 
    159     ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
    160 
    161     SockDiag sd;
    162     if (!sd.open()) {
    163         return binder::Status::fromServiceSpecificError(EIO,
    164                 String8("Could not open SOCK_DIAG socket"));
    165     }
    166 
    167     UidRanges uidRanges(uids);
    168     int err = sd.destroySockets(uidRanges, std::set<uid_t>(skipUids.begin(), skipUids.end()),
    169                                 true /* excludeLoopback */);
    170 
    171     if (err) {
    172         return binder::Status::fromServiceSpecificError(-err,
    173                 String8::format("destroySockets: %s", strerror(-err)));
    174     }
    175     return binder::Status::ok();
    176 }
    177 
    178 binder::Status NetdNativeService::setResolverConfiguration(int32_t netId,
    179         const std::vector<std::string>& servers, const std::vector<std::string>& domains,
    180         const std::vector<int32_t>& params) {
    181     // This function intentionally does not lock within Netd, as Bionic is thread-safe.
    182     ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
    183 
    184     int err = gCtls->resolverCtrl.setResolverConfiguration(netId, servers, domains, params);
    185     if (err != 0) {
    186         return binder::Status::fromServiceSpecificError(-err,
    187                 String8::format("ResolverController error: %s", strerror(-err)));
    188     }
    189     return binder::Status::ok();
    190 }
    191 
    192 binder::Status NetdNativeService::getResolverInfo(int32_t netId,
    193         std::vector<std::string>* servers, std::vector<std::string>* domains,
    194         std::vector<int32_t>* params, std::vector<int32_t>* stats) {
    195     // This function intentionally does not lock within Netd, as Bionic is thread-safe.
    196     ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
    197 
    198     int err = gCtls->resolverCtrl.getResolverInfo(netId, servers, domains, params, stats);
    199     if (err != 0) {
    200         return binder::Status::fromServiceSpecificError(-err,
    201                 String8::format("ResolverController error: %s", strerror(-err)));
    202     }
    203     return binder::Status::ok();
    204 }
    205 
    206 binder::Status NetdNativeService::tetherApplyDnsInterfaces(bool *ret) {
    207     NETD_BIG_LOCK_RPC(CONNECTIVITY_INTERNAL);
    208 
    209     *ret = gCtls->tetherCtrl.applyDnsInterfaces();
    210     return binder::Status::ok();
    211 }
    212 
    213 binder::Status NetdNativeService::interfaceAddAddress(const std::string &ifName,
    214         const std::string &addrString, int prefixLength) {
    215     ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
    216 
    217     const int err = InterfaceController::addAddress(
    218             ifName.c_str(), addrString.c_str(), prefixLength);
    219     if (err != 0) {
    220         return binder::Status::fromServiceSpecificError(-err,
    221                 String8::format("InterfaceController error: %s", strerror(-err)));
    222     }
    223     return binder::Status::ok();
    224 }
    225 
    226 binder::Status NetdNativeService::interfaceDelAddress(const std::string &ifName,
    227         const std::string &addrString, int prefixLength) {
    228     ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
    229 
    230     const int err = InterfaceController::delAddress(
    231             ifName.c_str(), addrString.c_str(), prefixLength);
    232     if (err != 0) {
    233         return binder::Status::fromServiceSpecificError(-err,
    234                 String8::format("InterfaceController error: %s", strerror(-err)));
    235     }
    236     return binder::Status::ok();
    237 }
    238 
    239 binder::Status NetdNativeService::setProcSysNet(
    240         int32_t family, int32_t which, const std::string &ifname, const std::string &parameter,
    241         const std::string &value) {
    242     ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
    243 
    244     const char *familyStr;
    245     switch (family) {
    246         case INetd::IPV4:
    247             familyStr = "ipv4";
    248             break;
    249         case INetd::IPV6:
    250             familyStr = "ipv6";
    251             break;
    252         default:
    253             return binder::Status::fromServiceSpecificError(EAFNOSUPPORT, String8("Bad family"));
    254     }
    255 
    256     const char *whichStr;
    257     switch (which) {
    258         case INetd::CONF:
    259             whichStr = "conf";
    260             break;
    261         case INetd::NEIGH:
    262             whichStr = "neigh";
    263             break;
    264         default:
    265             return binder::Status::fromServiceSpecificError(EINVAL, String8("Bad category"));
    266     }
    267 
    268     const int err = InterfaceController::setParameter(
    269             familyStr, whichStr, ifname.c_str(), parameter.c_str(),
    270             value.c_str());
    271     if (err != 0) {
    272         return binder::Status::fromServiceSpecificError(-err,
    273                 String8::format("ResolverController error: %s", strerror(-err)));
    274     }
    275     return binder::Status::ok();
    276 }
    277 
    278 }  // namespace net
    279 }  // namespace android
    280