blob: aace7be28a266a67463662272724568b77065f2f [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
17#define LOG_TAG "DnsResolverService"
18
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
24#include <android-base/stringprintf.h>
25#include <android-base/strings.h>
26#include <android/binder_manager.h>
27#include <android/binder_process.h>
28#include <log/log.h>
Luke Huang7b26b202019-03-28 14:09:24 +080029#include <openssl/base64.h>
Luke Huang403c0442019-02-25 15:33:42 +080030#include <private/android_filesystem_config.h> // AID_SYSTEM
31
Luke Huang36796f32019-03-13 02:54:45 +080032#include "DnsResolver.h"
Luke Huang7b26b202019-03-28 14:09:24 +080033#include "NetdConstants.h" // SHA256_SIZE
Luke Huang403c0442019-02-25 15:33:42 +080034#include "NetdPermissions.h" // PERM_*
Hungming Chena32c8c12019-01-25 10:47:40 +080035#include "ResolverEventReporter.h"
Luke Huang7b26b202019-03-28 14:09:24 +080036#include "netdutils/DumpWriter.h"
Luke Huang403c0442019-02-25 15:33:42 +080037
38using android::base::Join;
39using android::base::StringPrintf;
Luke Huang7b26b202019-03-28 14:09:24 +080040using android::netdutils::DumpWriter;
Luke Huang403c0442019-02-25 15:33:42 +080041
42namespace android {
43namespace net {
44
45namespace {
46
47#define ENFORCE_ANY_PERMISSION(...) \
48 do { \
49 ::ndk::ScopedAStatus status = checkAnyPermission({__VA_ARGS__}); \
50 if (!status.isOk()) { \
51 return status; \
52 } \
53 } while (0)
54
55#define ENFORCE_INTERNAL_PERMISSIONS() \
56 ENFORCE_ANY_PERMISSION(PERM_CONNECTIVITY_INTERNAL, PERM_MAINLINE_NETWORK_STACK)
57
58#define ENFORCE_NETWORK_STACK_PERMISSIONS() \
59 ENFORCE_ANY_PERMISSION(PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK)
60
Hungming Chena32c8c12019-01-25 10:47:40 +080061inline ::ndk::ScopedAStatus statusFromErrcode(int ret) {
62 if (ret) {
63 return ::ndk::ScopedAStatus(
64 AStatus_fromServiceSpecificErrorWithMessage(-ret, strerror(-ret)));
65 }
66 return ::ndk::ScopedAStatus(AStatus_newOk());
67}
68
Luke Huang403c0442019-02-25 15:33:42 +080069} // namespace
70
Luke Huang36796f32019-03-13 02:54:45 +080071binder_status_t DnsResolverService::start() {
Luke Huang403c0442019-02-25 15:33:42 +080072 // TODO: Add disableBackgroundScheduling(true) after libbinder_ndk support it. b/126506010
73 // NetdNativeService does call disableBackgroundScheduling currently, so it is fine now.
Luke Huang36796f32019-03-13 02:54:45 +080074 DnsResolverService* resolverService = new DnsResolverService();
Luke Huang403c0442019-02-25 15:33:42 +080075 binder_status_t status =
76 AServiceManager_addService(resolverService->asBinder().get(), getServiceName());
77 if (status != STATUS_OK) {
78 return status;
79 }
80
81 ABinderProcess_startThreadPool();
82
83 // TODO: register log callback if binder NDK backend support it. b/126501406
84
85 return STATUS_OK;
86}
87
Luke Huang7b26b202019-03-28 14:09:24 +080088binder_status_t DnsResolverService::dump(int, const char**, uint32_t) {
89 // TODO: Implement it. Netd binder dump resolver related log based on all stored network.
90 // However, resolver doesn't know that informations.
91 return STATUS_OK;
92}
93
Luke Huang403c0442019-02-25 15:33:42 +080094::ndk::ScopedAStatus DnsResolverService::isAlive(bool* alive) {
95 ENFORCE_INTERNAL_PERMISSIONS();
96
97 *alive = true;
98
99 return ::ndk::ScopedAStatus(AStatus_newOk());
100}
101
Hungming Chena32c8c12019-01-25 10:47:40 +0800102::ndk::ScopedAStatus DnsResolverService::registerEventListener(
103 const std::shared_ptr<aidl::android::net::metrics::INetdEventListener>& listener) {
104 ENFORCE_NETWORK_STACK_PERMISSIONS();
105
106 int res = ResolverEventReporter::getInstance().addListener(listener);
107
108 return statusFromErrcode(res);
109}
110
Luke Huang403c0442019-02-25 15:33:42 +0800111::ndk::ScopedAStatus DnsResolverService::checkAnyPermission(
112 const std::vector<const char*>& permissions) {
113 // TODO: Remove callback and move this to unnamed namespace after libbiner_ndk supports
114 // check_permission.
Luke Huang36796f32019-03-13 02:54:45 +0800115 if (!gResNetdCallbacks.check_calling_permission) {
Luke Huang403c0442019-02-25 15:33:42 +0800116 return ::ndk::ScopedAStatus(AStatus_fromExceptionCodeWithMessage(
117 EX_NULL_POINTER, "check_calling_permission is null"));
118 }
119 pid_t pid = AIBinder_getCallingPid();
120 uid_t uid = AIBinder_getCallingUid();
121
122 // If the caller is the system UID, don't check permissions.
123 // Otherwise, if the system server's binder thread pool is full, and all the threads are
124 // blocked on a thread that's waiting for us to complete, we deadlock. http://b/69389492
125 //
126 // From a security perspective, there is currently no difference, because:
127 // 1. The only permissions we check in netd's binder interface are CONNECTIVITY_INTERNAL
128 // and NETWORK_STACK, which the system server always has (or MAINLINE_NETWORK_STACK, which
129 // is equivalent to having both CONNECTIVITY_INTERNAL and NETWORK_STACK).
130 // 2. AID_SYSTEM always has all permissions. See ActivityManager#checkComponentPermission.
131 if (uid == AID_SYSTEM) {
132 return ::ndk::ScopedAStatus(AStatus_newOk());
133 }
134
135 for (const char* permission : permissions) {
Luke Huang36796f32019-03-13 02:54:45 +0800136 if (gResNetdCallbacks.check_calling_permission(permission)) {
Luke Huang403c0442019-02-25 15:33:42 +0800137 return ::ndk::ScopedAStatus(AStatus_newOk());
138 }
139 }
140
141 auto err = StringPrintf("UID %d / PID %d does not have any of the following permissions: %s",
142 uid, pid, Join(permissions, ',').c_str());
143 return ::ndk::ScopedAStatus(AStatus_fromExceptionCodeWithMessage(EX_SECURITY, err.c_str()));
144}
145
Luke Huang7b26b202019-03-28 14:09:24 +0800146namespace {
147
148// Parse a base64 encoded string into a vector of bytes.
149// On failure, return an empty vector.
150static std::vector<uint8_t> parseBase64(const std::string& input) {
151 std::vector<uint8_t> decoded;
152 size_t out_len;
153 if (EVP_DecodedLength(&out_len, input.size()) != 1) {
154 return decoded;
155 }
156 // out_len is now an upper bound on the output length.
157 decoded.resize(out_len);
158 if (EVP_DecodeBase64(decoded.data(), &out_len, decoded.size(),
159 reinterpret_cast<const uint8_t*>(input.data()), input.size()) == 1) {
160 // Possibly shrink the vector if the actual output was smaller than the bound.
161 decoded.resize(out_len);
162 } else {
163 decoded.clear();
164 }
165 if (out_len != SHA256_SIZE) {
166 decoded.clear();
167 }
168 return decoded;
169}
170
171} // namespace
172
173::ndk::ScopedAStatus DnsResolverService::setResolverConfiguration(
174 int32_t netId, const std::vector<std::string>& servers,
175 const std::vector<std::string>& domains, const std::vector<int32_t>& params,
176 const std::string& tlsName, const std::vector<std::string>& tlsServers,
177 const std::vector<std::string>& tlsFingerprints) {
178 // Locking happens in PrivateDnsConfiguration and res_* functions.
179 ENFORCE_INTERNAL_PERMISSIONS();
180
181 std::set<std::vector<uint8_t>> decoded_fingerprints;
182 for (const std::string& fingerprint : tlsFingerprints) {
183 std::vector<uint8_t> decoded = parseBase64(fingerprint);
184 if (decoded.empty()) {
185 return ::ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
186 EINVAL, "ResolverController error: bad fingerprint"));
187 }
188 decoded_fingerprints.emplace(decoded);
189 }
190
191 int err = gDnsResolv->resolverCtrl.setResolverConfiguration(
192 netId, servers, domains, params, tlsName, tlsServers, decoded_fingerprints);
193 if (err != 0) {
194 return ::ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
195 -err, StringPrintf("ResolverController error: %s", strerror(-err)).c_str()));
196 }
197 return ::ndk::ScopedAStatus(AStatus_newOk());
198}
199
200::ndk::ScopedAStatus DnsResolverService::getResolverInfo(
201 int32_t netId, std::vector<std::string>* servers, std::vector<std::string>* domains,
202 std::vector<std::string>* tlsServers, std::vector<int32_t>* params,
203 std::vector<int32_t>* stats, std::vector<int32_t>* wait_for_pending_req_timeout_count) {
204 // Locking happens in PrivateDnsConfiguration and res_* functions.
205 ENFORCE_NETWORK_STACK_PERMISSIONS();
206
207 int err = gDnsResolv->resolverCtrl.getResolverInfo(netId, servers, domains, tlsServers, params,
208 stats, wait_for_pending_req_timeout_count);
209 if (err != 0) {
210 return ::ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
211 -err, StringPrintf("ResolverController error: %s", strerror(-err)).c_str()));
212 }
213 return ::ndk::ScopedAStatus(AStatus_newOk());
214}
215
216::ndk::ScopedAStatus DnsResolverService::startPrefix64Discovery(int32_t netId) {
217 // Locking happens in Dns64Configuration.
218 ENFORCE_NETWORK_STACK_PERMISSIONS();
219 gDnsResolv->resolverCtrl.startPrefix64Discovery(netId);
220
221 return ::ndk::ScopedAStatus(AStatus_newOk());
222}
223
224::ndk::ScopedAStatus DnsResolverService::stopPrefix64Discovery(int32_t netId) {
225 // Locking happens in Dns64Configuration.
226 ENFORCE_NETWORK_STACK_PERMISSIONS();
227 gDnsResolv->resolverCtrl.stopPrefix64Discovery(netId);
228
229 return ::ndk::ScopedAStatus(AStatus_newOk());
230}
231
232::ndk::ScopedAStatus DnsResolverService::getPrefix64(int netId, std::string* stringPrefix) {
233 ENFORCE_NETWORK_STACK_PERMISSIONS();
234 netdutils::IPPrefix prefix{};
235 int err = gDnsResolv->resolverCtrl.getPrefix64(netId, &prefix);
236 if (err != 0) {
237 return ::ndk::ScopedAStatus(AStatus_fromServiceSpecificErrorWithMessage(
238 -err, StringPrintf("ResolverController error: %s", strerror(-err)).c_str()));
239 }
240 *stringPrefix = prefix.toString();
241
242 return ::ndk::ScopedAStatus(AStatus_newOk());
243}
244
Luke Huang403c0442019-02-25 15:33:42 +0800245} // namespace net
246} // namespace android