NetdNativeService.cpp revision dedd271d9961dbe8b99ffa7d54ffd63ac326f866
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 25#include <binder/IPCThreadState.h> 26#include <binder/IServiceManager.h> 27#include "android/net/BnNetd.h" 28 29#include "Controllers.h" 30#include "DumpWriter.h" 31#include "NetdConstants.h" 32#include "NetdNativeService.h" 33 34using android::base::StringPrintf; 35 36namespace android { 37namespace net { 38 39namespace { 40 41const char CONNECTIVITY_INTERNAL[] = "android.permission.CONNECTIVITY_INTERNAL"; 42const char DUMP[] = "android.permission.DUMP"; 43 44binder::Status checkPermission(const char *permission) { 45 pid_t pid; 46 uid_t uid; 47 48 if (checkCallingPermission(String16(permission), (int32_t *) &pid, (int32_t *) &uid)) { 49 return binder::Status::ok(); 50 } else { 51 auto err = StringPrintf("UID %d / PID %d lacks permission %s", uid, pid, permission); 52 return binder::Status::fromExceptionCode(binder::Status::EX_SECURITY, String8(err.c_str())); 53 } 54} 55 56#define ENFORCE_PERMISSION(permission) { \ 57 binder::Status status = checkPermission((permission)); \ 58 if (!status.isOk()) { \ 59 return status; \ 60 } \ 61} 62 63#define NETD_LOCKING_RPC(permission, lock) \ 64 ENFORCE_PERMISSION(permission); \ 65 android::RWLock::AutoWLock _lock(lock); 66 67#define NETD_BIG_LOCK_RPC(permission) NETD_LOCKING_RPC((permission), gBigNetdLock) 68 69} // namespace 70 71 72status_t NetdNativeService::start() { 73 IPCThreadState::self()->disableBackgroundScheduling(true); 74 status_t ret = BinderService<NetdNativeService>::publish(); 75 if (ret != android::OK) { 76 return ret; 77 } 78 sp<ProcessState> ps(ProcessState::self()); 79 ps->startThreadPool(); 80 ps->giveThreadPoolName(); 81 return android::OK; 82} 83 84status_t NetdNativeService::dump(int fd, const Vector<String16> & /* args */) { 85 const binder::Status dump_permission = checkPermission(DUMP); 86 if (!dump_permission.isOk()) { 87 const String8 msg(dump_permission.toString8()); 88 write(fd, msg.string(), msg.size()); 89 return PERMISSION_DENIED; 90 } 91 92 // This method does not grab any locks. If individual classes need locking 93 // their dump() methods MUST handle locking appropriately. 94 DumpWriter dw(fd); 95 dw.blankline(); 96 gCtls->netCtrl.dump(dw); 97 dw.blankline(); 98 99 return NO_ERROR; 100} 101 102binder::Status NetdNativeService::isAlive(bool *alive) { 103 NETD_BIG_LOCK_RPC(CONNECTIVITY_INTERNAL); 104 105 *alive = true; 106 return binder::Status::ok(); 107} 108 109binder::Status NetdNativeService::firewallReplaceUidChain(const android::String16& chainName, 110 bool isWhitelist, const std::vector<int32_t>& uids, bool *ret) { 111 NETD_LOCKING_RPC(CONNECTIVITY_INTERNAL, gCtls->firewallCtrl.lock); 112 113 android::String8 name = android::String8(chainName); 114 int err = gCtls->firewallCtrl.replaceUidChain(name.string(), isWhitelist, uids); 115 *ret = (err == 0); 116 return binder::Status::ok(); 117} 118 119binder::Status NetdNativeService::bandwidthEnableDataSaver(bool enable, bool *ret) { 120 NETD_LOCKING_RPC(CONNECTIVITY_INTERNAL, gCtls->bandwidthCtrl.lock); 121 122 int err = gCtls->bandwidthCtrl.enableDataSaver(enable); 123 *ret = (err == 0); 124 return binder::Status::ok(); 125} 126 127} // namespace net 128} // namespace android 129