1 /** 2 * Copyright (c) 2019, 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 "resolv" 18 19 #include "DnsResolverService.h" 20 21 #include <set> 22 #include <vector> 23 24 #include <BinderUtil.h> 25 #include <android-base/stringprintf.h> 26 #include <android-base/strings.h> 27 #include <android/binder_manager.h> 28 #include <android/binder_process.h> 29 #include <netdutils/DumpWriter.h> 30 #include <private/android_filesystem_config.h> // AID_SYSTEM 31 32 #include "DnsResolver.h" 33 #include "Experiments.h" 34 #include "NetdPermissions.h" // PERM_* 35 #include "PrivateDnsConfiguration.h" 36 #include "ResolverEventReporter.h" 37 #include "resolv_cache.h" 38 39 using aidl::android::net::ResolverOptionsParcel; 40 using aidl::android::net::ResolverParamsParcel; 41 using android::base::Join; 42 using android::base::StringPrintf; 43 using android::netdutils::DumpWriter; 44 using android::netdutils::IPPrefix; 45 46 namespace android { 47 namespace net { 48 49 namespace { 50 51 #define ENFORCE_ANY_PERMISSION(...) \ 52 do { \ 53 ::ndk::ScopedAStatus status = checkAnyPermission({__VA_ARGS__}); \ 54 if (!status.isOk()) { \ 55 return status; \ 56 } \ 57 } while (0) 58 59 #define ENFORCE_INTERNAL_PERMISSIONS() \ 60 ENFORCE_ANY_PERMISSION(PERM_CONNECTIVITY_INTERNAL, PERM_MAINLINE_NETWORK_STACK) 61 62 #define ENFORCE_NETWORK_STACK_PERMISSIONS() \ 63 ENFORCE_ANY_PERMISSION(PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK) 64 65 inline ::ndk::ScopedAStatus statusFromErrcode(int ret) { 66 if (ret) { 67 return ::ndk::ScopedAStatus( 68 AStatus_fromServiceSpecificErrorWithMessage(-ret, strerror(-ret))); 69 } 70 return ::ndk::ScopedAStatus(AStatus_newOk()); 71 } 72 73 } // namespace 74 75 DnsResolverService::DnsResolverService() { 76 // register log callback to BnDnsResolver::logFunc 77 BnDnsResolver::logFunc = [](const auto& log) { 78 binderCallLogFn(log, [](const std::string& msg) { gResNetdCallbacks.log(msg.c_str()); }); 79 }; 80 } 81 82 binder_status_t DnsResolverService::start() { 83 // TODO: Add disableBackgroundScheduling(true) after libbinder_ndk support it. b/126506010 84 // NetdNativeService does call disableBackgroundScheduling currently, so it is fine now. 85 std::shared_ptr<DnsResolverService> resolverService = 86 ::ndk::SharedRefBase::make<DnsResolverService>(); 87 binder_status_t status = 88 AServiceManager_addService(resolverService->asBinder().get(), getServiceName()); 89 if (status != STATUS_OK) { 90 return status; 91 } 92 93 ABinderProcess_startThreadPool(); 94 95 // TODO: register log callback if binder NDK backend support it. b/126501406 96 97 return STATUS_OK; 98 } 99 100 binder_status_t DnsResolverService::dump(int fd, const char** args, uint32_t numArgs) { 101 auto dump_permission = checkAnyPermission({PERM_DUMP}); 102 if (!dump_permission.isOk()) { 103 return STATUS_PERMISSION_DENIED; 104 } 105 106 // This method does not grab any locks. If individual classes need locking 107 // their dump() methods MUST handle locking appropriately. 108 DumpWriter dw(fd); 109 110 if (numArgs == 1 && std::string(args[0]) == DnsQueryLog::DUMP_KEYWORD) { 111 dw.blankline(); 112 gDnsResolv->dnsQueryLog().dump(dw); 113 dw.blankline(); 114 return STATUS_OK; 115 } 116 117 for (auto netId : resolv_list_caches()) { 118 dw.println("NetId: %u", netId); 119 gDnsResolv->resolverCtrl.dump(dw, netId); 120 dw.blankline(); 121 } 122 123 PrivateDnsConfiguration::getInstance().dump(dw); 124 Experiments::getInstance()->dump(dw); 125 return STATUS_OK; 126 } 127 128 ::ndk::ScopedAStatus DnsResolverService::isAlive(bool* alive) { 129 ENFORCE_INTERNAL_PERMISSIONS(); 130 131 *alive = true; 132 133 return ::ndk::ScopedAStatus(AStatus_newOk()); 134 } 135 136 ::ndk::ScopedAStatus DnsResolverService::registerEventListener( 137 const std::shared_ptr<aidl::android::net::metrics::INetdEventListener>& listener) { 138 ENFORCE_NETWORK_STACK_PERMISSIONS(); 139 140 int res = ResolverEventReporter::getInstance().addListener(listener); 141 142 return statusFromErrcode(res); 143 } 144 145 ::ndk::ScopedAStatus DnsResolverService::registerUnsolicitedEventListener( 146 const std::shared_ptr< 147 aidl::android::net::resolv::aidl::IDnsResolverUnsolicitedEventListener>& listener) { 148 ENFORCE_NETWORK_STACK_PERMISSIONS(); 149 150 int res = ResolverEventReporter::getInstance().addUnsolEventListener(listener); 151 152 return statusFromErrcode(res); 153 } 154 155 ::ndk::ScopedAStatus DnsResolverService::checkAnyPermission( 156 const std::vector<const char*>& permissions) { 157 // TODO: Remove callback and move this to unnamed namespace after libbiner_ndk supports 158 // check_permission. 159 if (!gResNetdCallbacks.check_calling_permission) { 160 return ::ndk::ScopedAStatus(AStatus_fromExceptionCodeWithMessage( 161 EX_NULL_POINTER, "check_calling_permission is null")); 162 } 163 pid_t pid = AIBinder_getCallingPid(); 164 uid_t uid = AIBinder_getCallingUid(); 165 166 // If the caller is the system UID, don't check permissions. 167 // Otherwise, if the system server's binder thread pool is full, and all the threads are 168 // blocked on a thread that's waiting for us to complete, we deadlock. http://b/69389492 169 // 170 // From a security perspective, there is currently no difference, because: 171 // 1. The only permissions we check in netd's binder interface are CONNECTIVITY_INTERNAL 172 // and NETWORK_STACK, which the system server always has (or MAINLINE_NETWORK_STACK, which 173 // is equivalent to having both CONNECTIVITY_INTERNAL and NETWORK_STACK). 174 // 2. AID_SYSTEM always has all permissions. See ActivityManager#checkComponentPermission. 175 if (uid == AID_SYSTEM) { 176 return ::ndk::ScopedAStatus(AStatus_newOk()); 177 } 178 179 for (const char* permission : permissions) { 180 if (gResNetdCallbacks.check_calling_permission(permission)) { 181 return ::ndk::ScopedAStatus(AStatus_newOk()); 182 } 183 } 184 185 auto err = StringPrintf("UID %d / PID %d does not have any of the following permissions: %s", 186 uid, pid, Join(permissions, ',').c_str()); 187 return ::ndk::ScopedAStatus(AStatus_fromExceptionCodeWithMessage(EX_SECURITY, err.c_str())); 188 } 189 190 ::ndk::ScopedAStatus DnsResolverService::setResolverConfiguration( 191 const ResolverParamsParcel& resolverParams) { 192 // Locking happens in PrivateDnsConfiguration and res_* functions. 193 ENFORCE_INTERNAL_PERMISSIONS(); 194 195 // TODO@: Switch to selinux based permission check if AIBinder_getCallingSid and 196 // AIBinder_setRequestingSid can be supported by libbinder_dnk (b/159135973). 197 uid_t uid = AIBinder_getCallingUid(); 198 // CAUTION: caCertificate should NOT be used except for internal testing. 199 if (resolverParams.caCertificate.size() != 0 && uid != AID_ROOT) { 200 auto err = StringPrintf("UID %d is not authorized to set a non-empty CA certificate", uid); 201 return ::ndk::ScopedAStatus(AStatus_fromExceptionCodeWithMessage(EX_SECURITY, err.c_str())); 202 } 203 204 // TODO: Remove this log after AIDL gen_log supporting more types, b/129732660 205 auto entry = 206 gDnsResolverLog.newEntry() 207 .prettyFunction(__PRETTY_FUNCTION__) 208 .args(resolverParams.netId, resolverParams.servers, resolverParams.domains, 209 resolverParams.sampleValiditySeconds, resolverParams.successThreshold, 210 resolverParams.minSamples, resolverParams.maxSamples, 211 resolverParams.baseTimeoutMsec, resolverParams.retryCount, 212 resolverParams.tlsName, resolverParams.tlsServers); 213 214 int res = gDnsResolv->resolverCtrl.setResolverConfiguration(resolverParams); 215 gResNetdCallbacks.log(entry.returns(res).withAutomaticDuration().toString().c_str()); 216 217 return statusFromErrcode(res); 218 } 219 220 ::ndk::ScopedAStatus DnsResolverService::getResolverInfo( 221 int32_t netId, std::vector<std::string>* servers, std::vector<std::string>* domains, 222 std::vector<std::string>* tlsServers, std::vector<int32_t>* params, 223 std::vector<int32_t>* stats, std::vector<int32_t>* wait_for_pending_req_timeout_count) { 224 // Locking happens in PrivateDnsConfiguration and res_* functions. 225 ENFORCE_NETWORK_STACK_PERMISSIONS(); 226 227 int res = gDnsResolv->resolverCtrl.getResolverInfo(netId, servers, domains, tlsServers, params, 228 stats, wait_for_pending_req_timeout_count); 229 230 return statusFromErrcode(res); 231 } 232 233 ::ndk::ScopedAStatus DnsResolverService::startPrefix64Discovery(int32_t netId) { 234 // Locking happens in Dns64Configuration. 235 ENFORCE_NETWORK_STACK_PERMISSIONS(); 236 237 gDnsResolv->resolverCtrl.startPrefix64Discovery(netId); 238 239 return ::ndk::ScopedAStatus(AStatus_newOk()); 240 } 241 242 ::ndk::ScopedAStatus DnsResolverService::stopPrefix64Discovery(int32_t netId) { 243 // Locking happens in Dns64Configuration. 244 ENFORCE_NETWORK_STACK_PERMISSIONS(); 245 246 gDnsResolv->resolverCtrl.stopPrefix64Discovery(netId); 247 248 return ::ndk::ScopedAStatus(AStatus_newOk()); 249 } 250 251 ::ndk::ScopedAStatus DnsResolverService::getPrefix64(int netId, std::string* stringPrefix) { 252 ENFORCE_NETWORK_STACK_PERMISSIONS(); 253 254 netdutils::IPPrefix prefix{}; 255 int res = gDnsResolv->resolverCtrl.getPrefix64(netId, &prefix); 256 *stringPrefix = prefix.toString(); 257 258 return statusFromErrcode(res); 259 } 260 261 ::ndk::ScopedAStatus DnsResolverService::setPrefix64(int netId, const std::string& stringPrefix) { 262 ENFORCE_NETWORK_STACK_PERMISSIONS(); 263 264 if (stringPrefix.empty()) { 265 return statusFromErrcode(gDnsResolv->resolverCtrl.clearPrefix64(netId)); 266 } 267 268 IPPrefix prefix; 269 if (!IPPrefix::forString(stringPrefix, &prefix)) { 270 return statusFromErrcode(-EINVAL); 271 } 272 273 return statusFromErrcode(gDnsResolv->resolverCtrl.setPrefix64(netId, prefix)); 274 } 275 276 ::ndk::ScopedAStatus DnsResolverService::setLogSeverity(int32_t logSeverity) { 277 ENFORCE_NETWORK_STACK_PERMISSIONS(); 278 279 int res = gDnsResolv->setLogSeverity(logSeverity); 280 281 return statusFromErrcode(res); 282 } 283 284 ::ndk::ScopedAStatus DnsResolverService::destroyNetworkCache(int netId) { 285 // Locking happens in res_cache.cpp functions. 286 ENFORCE_NETWORK_STACK_PERMISSIONS(); 287 288 gDnsResolv->resolverCtrl.destroyNetworkCache(netId); 289 Experiments::getInstance()->update(); 290 return ::ndk::ScopedAStatus(AStatus_newOk()); 291 } 292 293 ::ndk::ScopedAStatus DnsResolverService::createNetworkCache(int netId) { 294 // Locking happens in res_cache.cpp functions. 295 ENFORCE_NETWORK_STACK_PERMISSIONS(); 296 297 int res = gDnsResolv->resolverCtrl.createNetworkCache(netId); 298 Experiments::getInstance()->update(); 299 return statusFromErrcode(res); 300 } 301 302 ::ndk::ScopedAStatus DnsResolverService::flushNetworkCache(int netId) { 303 // Locking happens in res_cache.cpp functions. 304 ENFORCE_NETWORK_STACK_PERMISSIONS(); 305 306 int res = gDnsResolv->resolverCtrl.flushNetworkCache(netId); 307 308 return statusFromErrcode(res); 309 } 310 311 ::ndk::ScopedAStatus DnsResolverService::setResolverOptions(int32_t netId, 312 const ResolverOptionsParcel& options) { 313 // Locking happens in res_cache.cpp functions. 314 ENFORCE_NETWORK_STACK_PERMISSIONS(); 315 316 return statusFromErrcode(resolv_set_options(netId, options)); 317 } 318 319 } // namespace net 320 } // namespace android 321