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 ¶meter, 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