NetdNativeService.cpp revision e760181ff41a5f4526e4f543f3838eb05690e2aa
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 <cutils/properties.h>
24#include <utils/Errors.h>
25#include <utils/String16.h>
26
27#include <binder/IPCThreadState.h>
28#include <binder/IServiceManager.h>
29#include "android/net/BnNetd.h"
30
31#include <openssl/base64.h>
32
33#include "Controllers.h"
34#include "DumpWriter.h"
35#include "EventReporter.h"
36#include "InterfaceController.h"
37#include "NetdConstants.h"
38#include "NetdNativeService.h"
39#include "RouteController.h"
40#include "SockDiag.h"
41#include "UidRanges.h"
42
43using android::base::StringPrintf;
44
45namespace android {
46namespace net {
47
48namespace {
49
50const char CONNECTIVITY_INTERNAL[] = "android.permission.CONNECTIVITY_INTERNAL";
51const char NETWORK_STACK[] = "android.permission.NETWORK_STACK";
52const char DUMP[] = "android.permission.DUMP";
53
54binder::Status toBinderStatus(const netdutils::Status s) {
55    if (isOk(s)) {
56        return binder::Status::ok();
57    }
58    return binder::Status::fromServiceSpecificError(s.code(), s.msg().c_str());
59}
60
61binder::Status checkPermission(const char *permission) {
62    pid_t pid;
63    uid_t uid;
64
65    if (checkCallingPermission(String16(permission), (int32_t *) &pid, (int32_t *) &uid)) {
66        return binder::Status::ok();
67    } else {
68        auto err = StringPrintf("UID %d / PID %d lacks permission %s", uid, pid, permission);
69        return binder::Status::fromExceptionCode(binder::Status::EX_SECURITY, String8(err.c_str()));
70    }
71}
72
73binder::Status getXfrmStatus(int xfrmCode) {
74    switch(xfrmCode) {
75        case 0:
76            return binder::Status::ok();
77        case -ENOENT:
78            return binder::Status::fromServiceSpecificError(xfrmCode);
79    }
80    return binder::Status::fromExceptionCode(xfrmCode);
81}
82
83#define ENFORCE_DEBUGGABLE() {                              \
84    char value[PROPERTY_VALUE_MAX + 1];                     \
85    if (property_get("ro.debuggable", value, NULL) != 1     \
86            || value[0] != '1') {                           \
87        return binder::Status::fromExceptionCode(           \
88            binder::Status::EX_SECURITY,                    \
89            String8("Not available in production builds.")  \
90        );                                                  \
91    }                                                       \
92}
93
94#define ENFORCE_PERMISSION(permission) {                    \
95    binder::Status status = checkPermission((permission));  \
96    if (!status.isOk()) {                                   \
97        return status;                                      \
98    }                                                       \
99}
100
101#define NETD_LOCKING_RPC(permission, lock)                  \
102    ENFORCE_PERMISSION(permission);                         \
103    android::RWLock::AutoWLock _lock(lock);
104
105#define NETD_BIG_LOCK_RPC(permission) NETD_LOCKING_RPC((permission), gBigNetdLock)
106}  // namespace
107
108
109status_t NetdNativeService::start() {
110    IPCThreadState::self()->disableBackgroundScheduling(true);
111    status_t ret = BinderService<NetdNativeService>::publish();
112    if (ret != android::OK) {
113        return ret;
114    }
115    sp<ProcessState> ps(ProcessState::self());
116    ps->startThreadPool();
117    ps->giveThreadPoolName();
118    return android::OK;
119}
120
121status_t NetdNativeService::dump(int fd, const Vector<String16> & /* args */) {
122    const binder::Status dump_permission = checkPermission(DUMP);
123    if (!dump_permission.isOk()) {
124        const String8 msg(dump_permission.toString8());
125        write(fd, msg.string(), msg.size());
126        return PERMISSION_DENIED;
127    }
128
129    // This method does not grab any locks. If individual classes need locking
130    // their dump() methods MUST handle locking appropriately.
131    DumpWriter dw(fd);
132    dw.blankline();
133    gCtls->netCtrl.dump(dw);
134    dw.blankline();
135
136    return NO_ERROR;
137}
138
139binder::Status NetdNativeService::isAlive(bool *alive) {
140    NETD_BIG_LOCK_RPC(CONNECTIVITY_INTERNAL);
141
142    *alive = true;
143    return binder::Status::ok();
144}
145
146binder::Status NetdNativeService::firewallReplaceUidChain(const android::String16& chainName,
147        bool isWhitelist, const std::vector<int32_t>& uids, bool *ret) {
148    NETD_LOCKING_RPC(CONNECTIVITY_INTERNAL, gCtls->firewallCtrl.lock);
149
150    android::String8 name = android::String8(chainName);
151    int err = gCtls->firewallCtrl.replaceUidChain(name.string(), isWhitelist, uids);
152    *ret = (err == 0);
153    return binder::Status::ok();
154}
155
156binder::Status NetdNativeService::bandwidthEnableDataSaver(bool enable, bool *ret) {
157    NETD_LOCKING_RPC(CONNECTIVITY_INTERNAL, gCtls->bandwidthCtrl.lock);
158
159    int err = gCtls->bandwidthCtrl.enableDataSaver(enable);
160    *ret = (err == 0);
161    return binder::Status::ok();
162}
163
164binder::Status NetdNativeService::networkRejectNonSecureVpn(bool add,
165        const std::vector<UidRange>& uidRangeArray) {
166    // TODO: elsewhere RouteController is only used from the tethering and network controllers, so
167    // it should be possible to use the same lock as NetworkController. However, every call through
168    // the CommandListener "network" command will need to hold this lock too, not just the ones that
169    // read/modify network internal state (that is sufficient for ::dump() because it doesn't
170    // look at routes, but it's not enough here).
171    NETD_BIG_LOCK_RPC(CONNECTIVITY_INTERNAL);
172
173    UidRanges uidRanges(uidRangeArray);
174
175    int err;
176    if (add) {
177        err = RouteController::addUsersToRejectNonSecureNetworkRule(uidRanges);
178    } else {
179        err = RouteController::removeUsersFromRejectNonSecureNetworkRule(uidRanges);
180    }
181
182    if (err != 0) {
183        return binder::Status::fromServiceSpecificError(-err,
184                String8::format("RouteController error: %s", strerror(-err)));
185    }
186    return binder::Status::ok();
187}
188
189binder::Status NetdNativeService::socketDestroy(const std::vector<UidRange>& uids,
190        const std::vector<int32_t>& skipUids) {
191
192    ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
193
194    SockDiag sd;
195    if (!sd.open()) {
196        return binder::Status::fromServiceSpecificError(EIO,
197                String8("Could not open SOCK_DIAG socket"));
198    }
199
200    UidRanges uidRanges(uids);
201    int err = sd.destroySockets(uidRanges, std::set<uid_t>(skipUids.begin(), skipUids.end()),
202                                true /* excludeLoopback */);
203
204    if (err) {
205        return binder::Status::fromServiceSpecificError(-err,
206                String8::format("destroySockets: %s", strerror(-err)));
207    }
208    return binder::Status::ok();
209}
210
211binder::Status NetdNativeService::setResolverConfiguration(int32_t netId,
212        const std::vector<std::string>& servers, const std::vector<std::string>& domains,
213        const std::vector<int32_t>& params) {
214    // This function intentionally does not lock within Netd, as Bionic is thread-safe.
215    ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
216
217    int err = gCtls->resolverCtrl.setResolverConfiguration(netId, servers, domains, params);
218    if (err != 0) {
219        return binder::Status::fromServiceSpecificError(-err,
220                String8::format("ResolverController error: %s", strerror(-err)));
221    }
222    return binder::Status::ok();
223}
224
225binder::Status NetdNativeService::getResolverInfo(int32_t netId,
226        std::vector<std::string>* servers, std::vector<std::string>* domains,
227        std::vector<int32_t>* params, std::vector<int32_t>* stats) {
228    // This function intentionally does not lock within Netd, as Bionic is thread-safe.
229    ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
230
231    int err = gCtls->resolverCtrl.getResolverInfo(netId, servers, domains, params, stats);
232    if (err != 0) {
233        return binder::Status::fromServiceSpecificError(-err,
234                String8::format("ResolverController error: %s", strerror(-err)));
235    }
236    return binder::Status::ok();
237}
238
239binder::Status NetdNativeService::addPrivateDnsServer(const std::string& server, int32_t port,
240        const std::string& fingerprintAlgorithm, const std::vector<std::string>& fingerprints) {
241    ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
242    std::set<std::vector<uint8_t>> decoded_fingerprints;
243    for (const std::string& input : fingerprints) {
244        size_t out_len;
245        if (EVP_DecodedLength(&out_len, input.size()) != 1) {
246            return binder::Status::fromServiceSpecificError(INetd::PRIVATE_DNS_BAD_FINGERPRINT,
247                    "ResolverController error: bad fingerprint length");
248        }
249        // out_len is now an upper bound on the output length.
250        std::vector<uint8_t> decoded(out_len);
251        if (EVP_DecodeBase64(decoded.data(), &out_len, decoded.size(),
252                reinterpret_cast<const uint8_t*>(input.data()), input.size()) == 1) {
253            // Possibly shrink the vector if the actual output was smaller than the bound.
254            decoded.resize(out_len);
255        } else {
256            return binder::Status::fromServiceSpecificError(INetd::PRIVATE_DNS_BAD_FINGERPRINT,
257                    "ResolverController error: Base64 parsing failed");
258        }
259        decoded_fingerprints.insert(decoded);
260    }
261    const int err = gCtls->resolverCtrl.addPrivateDnsServer(server, port,
262            fingerprintAlgorithm, decoded_fingerprints);
263    if (err != INetd::PRIVATE_DNS_SUCCESS) {
264        return binder::Status::fromServiceSpecificError(err,
265                String8::format("ResolverController error: %d", err));
266    }
267    return binder::Status::ok();
268}
269
270binder::Status NetdNativeService::removePrivateDnsServer(const std::string& server) {
271    ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
272    const int err = gCtls->resolverCtrl.removePrivateDnsServer(server);
273    if (err != INetd::PRIVATE_DNS_SUCCESS) {
274        return binder::Status::fromServiceSpecificError(err,
275                String8::format("ResolverController error: %d", err));
276    }
277    return binder::Status::ok();
278}
279
280binder::Status NetdNativeService::tetherApplyDnsInterfaces(bool *ret) {
281    NETD_BIG_LOCK_RPC(CONNECTIVITY_INTERNAL);
282
283    *ret = gCtls->tetherCtrl.applyDnsInterfaces();
284    return binder::Status::ok();
285}
286
287binder::Status NetdNativeService::interfaceAddAddress(const std::string &ifName,
288        const std::string &addrString, int prefixLength) {
289    ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
290
291    const int err = InterfaceController::addAddress(
292            ifName.c_str(), addrString.c_str(), prefixLength);
293    if (err != 0) {
294        return binder::Status::fromServiceSpecificError(-err,
295                String8::format("InterfaceController error: %s", strerror(-err)));
296    }
297    return binder::Status::ok();
298}
299
300binder::Status NetdNativeService::interfaceDelAddress(const std::string &ifName,
301        const std::string &addrString, int prefixLength) {
302    ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
303
304    const int err = InterfaceController::delAddress(
305            ifName.c_str(), addrString.c_str(), prefixLength);
306    if (err != 0) {
307        return binder::Status::fromServiceSpecificError(-err,
308                String8::format("InterfaceController error: %s", strerror(-err)));
309    }
310    return binder::Status::ok();
311}
312
313binder::Status NetdNativeService::setProcSysNet(
314        int32_t family, int32_t which, const std::string &ifname, const std::string &parameter,
315        const std::string &value) {
316    ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
317
318    const char *familyStr;
319    switch (family) {
320        case INetd::IPV4:
321            familyStr = "ipv4";
322            break;
323        case INetd::IPV6:
324            familyStr = "ipv6";
325            break;
326        default:
327            return binder::Status::fromServiceSpecificError(EAFNOSUPPORT, String8("Bad family"));
328    }
329
330    const char *whichStr;
331    switch (which) {
332        case INetd::CONF:
333            whichStr = "conf";
334            break;
335        case INetd::NEIGH:
336            whichStr = "neigh";
337            break;
338        default:
339            return binder::Status::fromServiceSpecificError(EINVAL, String8("Bad category"));
340    }
341
342    const int err = InterfaceController::setParameter(
343            familyStr, whichStr, ifname.c_str(), parameter.c_str(),
344            value.c_str());
345    if (err != 0) {
346        return binder::Status::fromServiceSpecificError(-err,
347                String8::format("ResolverController error: %s", strerror(-err)));
348    }
349    return binder::Status::ok();
350}
351
352binder::Status NetdNativeService::getMetricsReportingLevel(int *reportingLevel) {
353    // This function intentionally does not lock, since the only thing it does is one read from an
354    // atomic_int.
355    ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
356    ENFORCE_DEBUGGABLE();
357
358    *reportingLevel = gCtls->eventReporter.getMetricsReportingLevel();
359    return binder::Status::ok();
360}
361
362binder::Status NetdNativeService::setMetricsReportingLevel(const int reportingLevel) {
363    // This function intentionally does not lock, since the only thing it does is one write to an
364    // atomic_int.
365    ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
366    ENFORCE_DEBUGGABLE();
367
368    return (gCtls->eventReporter.setMetricsReportingLevel(reportingLevel) == 0)
369            ? binder::Status::ok()
370            : binder::Status::fromExceptionCode(binder::Status::EX_ILLEGAL_ARGUMENT);
371}
372
373binder::Status NetdNativeService::ipSecAllocateSpi(
374        int32_t transformId,
375        int32_t direction,
376        const std::string& localAddress,
377        const std::string& remoteAddress,
378        int32_t inSpi,
379        int32_t* outSpi) {
380    // Necessary locking done in IpSecService and kernel
381    ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
382    ALOGD("ipSecAllocateSpi()");
383    return getXfrmStatus(gCtls->xfrmCtrl.ipSecAllocateSpi(
384                    transformId,
385                    direction,
386                    localAddress,
387                    remoteAddress,
388                    inSpi,
389                    outSpi));
390}
391
392binder::Status NetdNativeService::ipSecAddSecurityAssociation(
393        int32_t transformId,
394        int32_t mode,
395        int32_t direction,
396        const std::string& localAddress,
397        const std::string& remoteAddress,
398        int64_t underlyingNetworkHandle,
399        int32_t spi,
400        const std::string& authAlgo, const std::vector<uint8_t>& authKey, int32_t authTruncBits,
401        const std::string& cryptAlgo, const std::vector<uint8_t>& cryptKey, int32_t cryptTruncBits,
402        int32_t encapType,
403        int32_t encapLocalPort,
404        int32_t encapRemotePort,
405        int32_t* allocatedSpi) {
406    // Necessary locking done in IpSecService and kernel
407    ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
408    ALOGD("ipSecAddSecurityAssociation()");
409    return getXfrmStatus(gCtls->xfrmCtrl.ipSecAddSecurityAssociation(
410              transformId, mode, direction, localAddress, remoteAddress,
411              underlyingNetworkHandle,
412              spi,
413              authAlgo, authKey, authTruncBits,
414              cryptAlgo, cryptKey, cryptTruncBits,
415              encapType, encapLocalPort, encapRemotePort,
416              allocatedSpi));
417}
418
419binder::Status NetdNativeService::ipSecDeleteSecurityAssociation(
420        int32_t transformId,
421        int32_t direction,
422        const std::string& localAddress,
423        const std::string& remoteAddress,
424        int32_t spi) {
425    // Necessary locking done in IpSecService and kernel
426    ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
427    ALOGD("ipSecDeleteSecurityAssociation()");
428    return getXfrmStatus(gCtls->xfrmCtrl.ipSecDeleteSecurityAssociation(
429                    transformId,
430                    direction,
431                    localAddress,
432                    remoteAddress,
433                    spi));
434}
435
436binder::Status NetdNativeService::ipSecApplyTransportModeTransform(
437        const android::base::unique_fd& socket,
438        int32_t transformId,
439        int32_t direction,
440        const std::string& localAddress,
441        const std::string& remoteAddress,
442        int32_t spi) {
443    // Necessary locking done in IpSecService and kernel
444    ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
445    ALOGD("ipSecApplyTransportModeTransform()");
446    return getXfrmStatus(gCtls->xfrmCtrl.ipSecApplyTransportModeTransform(
447                    socket,
448                    transformId,
449                    direction,
450                    localAddress,
451                    remoteAddress,
452                    spi));
453}
454
455binder::Status NetdNativeService::ipSecRemoveTransportModeTransform(
456            const android::base::unique_fd& socket) {
457    // Necessary locking done in IpSecService and kernel
458    ENFORCE_PERMISSION(CONNECTIVITY_INTERNAL);
459    ALOGD("ipSecRemoveTransportModeTransform()");
460    return getXfrmStatus(gCtls->xfrmCtrl.ipSecRemoveTransportModeTransform(
461                    socket));
462}
463
464binder::Status NetdNativeService::setIPv6AddrGenMode(const std::string& ifName,
465                                                     int32_t mode) {
466    ENFORCE_PERMISSION(NETWORK_STACK);
467    return toBinderStatus(InterfaceController::setIPv6AddrGenMode(ifName, mode));
468}
469
470binder::Status NetdNativeService::wakeupAddInterface(const std::string& ifName,
471                                                     const std::string& prefix, int32_t mark,
472                                                     int32_t mask) {
473    ENFORCE_PERMISSION(NETWORK_STACK);
474    return toBinderStatus(gCtls->wakeupCtrl.addInterface(ifName, prefix, mark, mask));
475}
476
477binder::Status NetdNativeService::wakeupDelInterface(const std::string& ifName,
478                                                     const std::string& prefix, int32_t mark,
479                                                     int32_t mask) {
480    ENFORCE_PERMISSION(NETWORK_STACK);
481    return toBinderStatus(gCtls->wakeupCtrl.delInterface(ifName, prefix, mark, mask));
482}
483
484}  // namespace net
485}  // namespace android
486