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