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
39using android::base::StringPrintf;
40
41namespace android {
42namespace net {
43
44namespace {
45
46const char CONNECTIVITY_INTERNAL[] = "android.permission.CONNECTIVITY_INTERNAL";
47const char DUMP[] = "android.permission.DUMP";
48
49binder::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
76status_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
88status_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
106binder::Status NetdNativeService::isAlive(bool *alive) {
107    NETD_BIG_LOCK_RPC(CONNECTIVITY_INTERNAL);
108
109    *alive = true;
110    return binder::Status::ok();
111}
112
113binder::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
123binder::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
131binder::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
156binder::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
178binder::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
192binder::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
206binder::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
213binder::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
226binder::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
239binder::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