blob: 8319832692a768dd04e47abe9454e9315af5ecac [file] [log] [blame]
Luke Huang403c0442019-02-25 15:33:42 +08001/**
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
Ken Chen5471dca2019-04-15 15:25:35 +080017#define LOG_TAG "resolv"
Luke Huang403c0442019-02-25 15:33:42 +080018
Luke Huang36796f32019-03-13 02:54:45 +080019#include "DnsResolverService.h"
20
Luke Huang403c0442019-02-25 15:33:42 +080021#include <set>
22#include <vector>
23
Luke Huangf4c98f22019-06-14 01:57:00 +080024#include <BinderUtil.h>
Luke Huang403c0442019-02-25 15:33:42 +080025#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 <log/log.h>
Luke Huang598daad2019-05-02 18:10:15 +080030#include <netdutils/DumpWriter.h>
Luke Huang579ddc72019-06-14 00:59:39 +080031#include <netdutils/NetworkConstants.h> // SHA256_SIZE
Luke Huang7b26b202019-03-28 14:09:24 +080032#include <openssl/base64.h>
Luke Huang403c0442019-02-25 15:33:42 +080033#include <private/android_filesystem_config.h> // AID_SYSTEM
34
Luke Huang36796f32019-03-13 02:54:45 +080035#include "DnsResolver.h"
Luke Huang403c0442019-02-25 15:33:42 +080036#include "NetdPermissions.h" // PERM_*
Hungming Chena32c8c12019-01-25 10:47:40 +080037#include "ResolverEventReporter.h"
Luke Huangc6bbbe72019-03-28 21:38:28 +080038#include "resolv_cache.h"
Luke Huang403c0442019-02-25 15:33:42 +080039
waynema37255182019-03-18 13:22:56 +080040using aidl::android::net::ResolverParamsParcel;
Luke Huang403c0442019-02-25 15:33:42 +080041using android::base::Join;
42using android::base::StringPrintf;
Luke Huang7b26b202019-03-28 14:09:24 +080043using android::netdutils::DumpWriter;
Luke Huang403c0442019-02-25 15:33:42 +080044
45namespace android {
46namespace net {
47
48namespace {
49
50#define ENFORCE_ANY_PERMISSION(...) \
51 do { \
52 ::ndk::ScopedAStatus status = checkAnyPermission({__VA_ARGS__}); \
53 if (!status.isOk()) { \
54 return status; \
55 } \
56 } while (0)
57
58#define ENFORCE_INTERNAL_PERMISSIONS() \
59 ENFORCE_ANY_PERMISSION(PERM_CONNECTIVITY_INTERNAL, PERM_MAINLINE_NETWORK_STACK)
60
61#define ENFORCE_NETWORK_STACK_PERMISSIONS() \
62 ENFORCE_ANY_PERMISSION(PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK)
63
Hungming Chena32c8c12019-01-25 10:47:40 +080064inline ::ndk::ScopedAStatus statusFromErrcode(int ret) {
65 if (ret) {
66 return ::ndk::ScopedAStatus(
67 AStatus_fromServiceSpecificErrorWithMessage(-ret, strerror(-ret)));
68 }
69 return ::ndk::ScopedAStatus(AStatus_newOk());
70}
71
Luke Huang403c0442019-02-25 15:33:42 +080072} // namespace
73
Luke Huang598daad2019-05-02 18:10:15 +080074DnsResolverService::DnsResolverService() {
75 // register log callback to BnDnsResolver::logFunc
76 BnDnsResolver::logFunc =
77 std::bind(binderCallLogFn, std::placeholders::_1,
78 [](const std::string& msg) { gResNetdCallbacks.log(msg.c_str()); });
79}
80
Luke Huang36796f32019-03-13 02:54:45 +080081binder_status_t DnsResolverService::start() {
Luke Huang403c0442019-02-25 15:33:42 +080082 // TODO: Add disableBackgroundScheduling(true) after libbinder_ndk support it. b/126506010
83 // NetdNativeService does call disableBackgroundScheduling currently, so it is fine now.
Luke Huang36796f32019-03-13 02:54:45 +080084 DnsResolverService* resolverService = new DnsResolverService();
Luke Huang403c0442019-02-25 15:33:42 +080085 binder_status_t status =
86 AServiceManager_addService(resolverService->asBinder().get(), getServiceName());
87 if (status != STATUS_OK) {
88 return status;
89 }
90
91 ABinderProcess_startThreadPool();
92
93 // TODO: register log callback if binder NDK backend support it. b/126501406
94
95 return STATUS_OK;
96}
97
Luke Huangc6bbbe72019-03-28 21:38:28 +080098binder_status_t DnsResolverService::dump(int fd, const char**, uint32_t) {
99 auto dump_permission = checkAnyPermission({PERM_DUMP});
100 if (!dump_permission.isOk()) {
101 return STATUS_PERMISSION_DENIED;
102 }
103
104 // This method does not grab any locks. If individual classes need locking
105 // their dump() methods MUST handle locking appropriately.
106 DumpWriter dw(fd);
107 for (auto netId : resolv_list_caches()) {
108 dw.println("NetId: %u", netId);
109 gDnsResolv->resolverCtrl.dump(dw, netId);
110 dw.blankline();
111 }
112
Luke Huang7b26b202019-03-28 14:09:24 +0800113 return STATUS_OK;
114}
115
Luke Huang403c0442019-02-25 15:33:42 +0800116::ndk::ScopedAStatus DnsResolverService::isAlive(bool* alive) {
117 ENFORCE_INTERNAL_PERMISSIONS();
118
119 *alive = true;
120
121 return ::ndk::ScopedAStatus(AStatus_newOk());
122}
123
Hungming Chena32c8c12019-01-25 10:47:40 +0800124::ndk::ScopedAStatus DnsResolverService::registerEventListener(
125 const std::shared_ptr<aidl::android::net::metrics::INetdEventListener>& listener) {
126 ENFORCE_NETWORK_STACK_PERMISSIONS();
127
128 int res = ResolverEventReporter::getInstance().addListener(listener);
129
130 return statusFromErrcode(res);
131}
132
Luke Huang403c0442019-02-25 15:33:42 +0800133::ndk::ScopedAStatus DnsResolverService::checkAnyPermission(
134 const std::vector<const char*>& permissions) {
135 // TODO: Remove callback and move this to unnamed namespace after libbiner_ndk supports
136 // check_permission.
Luke Huang36796f32019-03-13 02:54:45 +0800137 if (!gResNetdCallbacks.check_calling_permission) {
Luke Huang403c0442019-02-25 15:33:42 +0800138 return ::ndk::ScopedAStatus(AStatus_fromExceptionCodeWithMessage(
139 EX_NULL_POINTER, "check_calling_permission is null"));
140 }
141 pid_t pid = AIBinder_getCallingPid();
142 uid_t uid = AIBinder_getCallingUid();
143
144 // If the caller is the system UID, don't check permissions.
145 // Otherwise, if the system server's binder thread pool is full, and all the threads are
146 // blocked on a thread that's waiting for us to complete, we deadlock. http://b/69389492
147 //
148 // From a security perspective, there is currently no difference, because:
149 // 1. The only permissions we check in netd's binder interface are CONNECTIVITY_INTERNAL
150 // and NETWORK_STACK, which the system server always has (or MAINLINE_NETWORK_STACK, which
151 // is equivalent to having both CONNECTIVITY_INTERNAL and NETWORK_STACK).
152 // 2. AID_SYSTEM always has all permissions. See ActivityManager#checkComponentPermission.
153 if (uid == AID_SYSTEM) {
154 return ::ndk::ScopedAStatus(AStatus_newOk());
155 }
156
157 for (const char* permission : permissions) {
Luke Huang36796f32019-03-13 02:54:45 +0800158 if (gResNetdCallbacks.check_calling_permission(permission)) {
Luke Huang403c0442019-02-25 15:33:42 +0800159 return ::ndk::ScopedAStatus(AStatus_newOk());
160 }
161 }
162
163 auto err = StringPrintf("UID %d / PID %d does not have any of the following permissions: %s",
164 uid, pid, Join(permissions, ',').c_str());
165 return ::ndk::ScopedAStatus(AStatus_fromExceptionCodeWithMessage(EX_SECURITY, err.c_str()));
166}
167
Luke Huang7b26b202019-03-28 14:09:24 +0800168namespace {
169
170// Parse a base64 encoded string into a vector of bytes.
171// On failure, return an empty vector.
172static std::vector<uint8_t> parseBase64(const std::string& input) {
173 std::vector<uint8_t> decoded;
174 size_t out_len;
175 if (EVP_DecodedLength(&out_len, input.size()) != 1) {
176 return decoded;
177 }
178 // out_len is now an upper bound on the output length.
179 decoded.resize(out_len);
180 if (EVP_DecodeBase64(decoded.data(), &out_len, decoded.size(),
181 reinterpret_cast<const uint8_t*>(input.data()), input.size()) == 1) {
182 // Possibly shrink the vector if the actual output was smaller than the bound.
183 decoded.resize(out_len);
184 } else {
185 decoded.clear();
186 }
Luke Huang579ddc72019-06-14 00:59:39 +0800187 if (out_len != android::netdutils::SHA256_SIZE) {
Luke Huang7b26b202019-03-28 14:09:24 +0800188 decoded.clear();
189 }
190 return decoded;
191}
192
193} // namespace
194
195::ndk::ScopedAStatus DnsResolverService::setResolverConfiguration(
waynema37255182019-03-18 13:22:56 +0800196 const ResolverParamsParcel& resolverParams) {
Luke Huang7b26b202019-03-28 14:09:24 +0800197 // Locking happens in PrivateDnsConfiguration and res_* functions.
198 ENFORCE_INTERNAL_PERMISSIONS();
Luke Huang598daad2019-05-02 18:10:15 +0800199 // TODO: Remove this log after AIDL gen_log supporting more types, b/129732660
Luke Huangc6bbbe72019-03-28 21:38:28 +0800200 auto entry =
201 gDnsResolverLog.newEntry()
202 .prettyFunction(__PRETTY_FUNCTION__)
waynema37255182019-03-18 13:22:56 +0800203 .args(resolverParams.netId, resolverParams.servers, resolverParams.domains,
204 resolverParams.sampleValiditySeconds, resolverParams.successThreshold,
205 resolverParams.minSamples, resolverParams.maxSamples,
waynema9a530232019-04-18 19:13:26 +0800206 resolverParams.baseTimeoutMsec, resolverParams.retryCount,
207 resolverParams.tlsServers, resolverParams.tlsFingerprints);
Luke Huang7b26b202019-03-28 14:09:24 +0800208
209 std::set<std::vector<uint8_t>> decoded_fingerprints;
waynema37255182019-03-18 13:22:56 +0800210 for (const std::string& fingerprint : resolverParams.tlsFingerprints) {
Luke Huang7b26b202019-03-28 14:09:24 +0800211 std::vector<uint8_t> decoded = parseBase64(fingerprint);
212 if (decoded.empty()) {
213 return ::ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
214 EINVAL, "ResolverController error: bad fingerprint"));
215 }
216 decoded_fingerprints.emplace(decoded);
217 }
218
Luke Huang598daad2019-05-02 18:10:15 +0800219 int res =
waynema37255182019-03-18 13:22:56 +0800220 gDnsResolv->resolverCtrl.setResolverConfiguration(resolverParams, decoded_fingerprints);
Luke Huangc6bbbe72019-03-28 21:38:28 +0800221
Luke Huang598daad2019-05-02 18:10:15 +0800222 gResNetdCallbacks.log(entry.returns(res).withAutomaticDuration().toString().c_str());
223
224 return statusFromErrcode(res);
Luke Huang7b26b202019-03-28 14:09:24 +0800225}
226
227::ndk::ScopedAStatus DnsResolverService::getResolverInfo(
228 int32_t netId, std::vector<std::string>* servers, std::vector<std::string>* domains,
229 std::vector<std::string>* tlsServers, std::vector<int32_t>* params,
230 std::vector<int32_t>* stats, std::vector<int32_t>* wait_for_pending_req_timeout_count) {
231 // Locking happens in PrivateDnsConfiguration and res_* functions.
232 ENFORCE_NETWORK_STACK_PERMISSIONS();
233
Luke Huang598daad2019-05-02 18:10:15 +0800234 int res = gDnsResolv->resolverCtrl.getResolverInfo(netId, servers, domains, tlsServers, params,
Luke Huang7b26b202019-03-28 14:09:24 +0800235 stats, wait_for_pending_req_timeout_count);
Luke Huangc6bbbe72019-03-28 21:38:28 +0800236
Luke Huang598daad2019-05-02 18:10:15 +0800237 return statusFromErrcode(res);
Luke Huang7b26b202019-03-28 14:09:24 +0800238}
239
240::ndk::ScopedAStatus DnsResolverService::startPrefix64Discovery(int32_t netId) {
241 // Locking happens in Dns64Configuration.
242 ENFORCE_NETWORK_STACK_PERMISSIONS();
Luke Huangc6bbbe72019-03-28 21:38:28 +0800243
Luke Huang7b26b202019-03-28 14:09:24 +0800244 gDnsResolv->resolverCtrl.startPrefix64Discovery(netId);
245
246 return ::ndk::ScopedAStatus(AStatus_newOk());
247}
248
249::ndk::ScopedAStatus DnsResolverService::stopPrefix64Discovery(int32_t netId) {
250 // Locking happens in Dns64Configuration.
251 ENFORCE_NETWORK_STACK_PERMISSIONS();
Luke Huangc6bbbe72019-03-28 21:38:28 +0800252
Luke Huang7b26b202019-03-28 14:09:24 +0800253 gDnsResolv->resolverCtrl.stopPrefix64Discovery(netId);
254
255 return ::ndk::ScopedAStatus(AStatus_newOk());
256}
257
258::ndk::ScopedAStatus DnsResolverService::getPrefix64(int netId, std::string* stringPrefix) {
259 ENFORCE_NETWORK_STACK_PERMISSIONS();
Luke Huangc6bbbe72019-03-28 21:38:28 +0800260
Luke Huang7b26b202019-03-28 14:09:24 +0800261 netdutils::IPPrefix prefix{};
Luke Huang598daad2019-05-02 18:10:15 +0800262 int res = gDnsResolv->resolverCtrl.getPrefix64(netId, &prefix);
Luke Huang7b26b202019-03-28 14:09:24 +0800263 *stringPrefix = prefix.toString();
264
Luke Huang598daad2019-05-02 18:10:15 +0800265 return statusFromErrcode(res);
Luke Huang7b26b202019-03-28 14:09:24 +0800266}
267
Ken Chend99022c2019-02-20 21:34:14 +0800268::ndk::ScopedAStatus DnsResolverService::setLogSeverity(int32_t logSeverity) {
269 ENFORCE_NETWORK_STACK_PERMISSIONS();
Luke Huang598daad2019-05-02 18:10:15 +0800270
Ken Chend99022c2019-02-20 21:34:14 +0800271 int res = gDnsResolv->setLogSeverity(logSeverity);
272
Ken Chend99022c2019-02-20 21:34:14 +0800273 return statusFromErrcode(res);
274}
275
Luke Huang9b80e6c2019-04-09 17:54:09 +0800276::ndk::ScopedAStatus DnsResolverService::destroyNetworkCache(int netId) {
277 // Locking happens in res_cache.cpp functions.
Luke Huang5bd827c2019-03-14 16:10:04 +0800278 ENFORCE_NETWORK_STACK_PERMISSIONS();
279
Luke Huang9b80e6c2019-04-09 17:54:09 +0800280 gDnsResolv->resolverCtrl.destroyNetworkCache(netId);
Luke Huangc6bbbe72019-03-28 21:38:28 +0800281
Luke Huang5bd827c2019-03-14 16:10:04 +0800282 return ::ndk::ScopedAStatus(AStatus_newOk());
283}
284
Luke Huang9b80e6c2019-04-09 17:54:09 +0800285::ndk::ScopedAStatus DnsResolverService::createNetworkCache(int netId) {
286 // Locking happens in res_cache.cpp functions.
287 ENFORCE_NETWORK_STACK_PERMISSIONS();
Luke Huang9b80e6c2019-04-09 17:54:09 +0800288
289 int res = gDnsResolv->resolverCtrl.createNetworkCache(netId);
290
Luke Huang9b80e6c2019-04-09 17:54:09 +0800291 return statusFromErrcode(res);
292}
293
Luke Huang403c0442019-02-25 15:33:42 +0800294} // namespace net
295} // namespace android