• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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 #include "DnsProxyListener.h"
18 
19 #include <arpa/inet.h>
20 #include <dirent.h>
21 #include <errno.h>
22 #include <linux/if.h>
23 #include <math.h>
24 #include <net/if.h>
25 #include <netdb.h>
26 #include <netinet/in.h>
27 #include <resolv.h>  // b64_pton()
28 #include <stdlib.h>
29 #include <string.h>
30 #include <sys/socket.h>
31 
32 #define LOG_TAG "resolv"
33 
34 #include <algorithm>
35 #include <vector>
36 
37 #include <android/multinetwork.h>  // ResNsendFlags
38 #include <cutils/misc.h>           // FIRST_APPLICATION_UID
39 #include <cutils/multiuser.h>
40 #include <netdutils/InternetAddresses.h>
41 #include <netdutils/ResponseCode.h>
42 #include <netdutils/Stopwatch.h>
43 #include <netdutils/ThreadUtil.h>
44 #include <private/android_filesystem_config.h>  // AID_SYSTEM
45 #include <statslog_resolv.h>
46 #include <sysutils/SocketClient.h>
47 
48 #include "DnsResolver.h"
49 #include "Experiments.h"
50 #include "NetdPermissions.h"
51 #include "OperationLimiter.h"
52 #include "PrivateDnsConfiguration.h"
53 #include "ResolverEventReporter.h"
54 #include "dnsproxyd_protocol/DnsProxydProtocol.h"  // NETID_USE_LOCAL_NAMESERVERS
55 #include "getaddrinfo.h"
56 #include "gethnamaddr.h"
57 #include "res_send.h"
58 #include "resolv_cache.h"
59 #include "resolv_private.h"
60 #include "stats.h"  // RCODE_TIMEOUT
61 #include "stats.pb.h"
62 
63 using aidl::android::net::metrics::INetdEventListener;
64 using aidl::android::net::resolv::aidl::DnsHealthEventParcel;
65 using aidl::android::net::resolv::aidl::IDnsResolverUnsolicitedEventListener;
66 using std::span;
67 
68 namespace android {
69 
70 using netdutils::ResponseCode;
71 using netdutils::Stopwatch;
72 
73 namespace net {
74 namespace {
75 
76 // Limits the number of outstanding DNS queries by client UID.
77 constexpr int MAX_QUERIES_PER_UID = 256;
78 
79 android::netdutils::OperationLimiter<uid_t> queryLimiter(MAX_QUERIES_PER_UID);
80 
logArguments(int argc,char ** argv)81 void logArguments(int argc, char** argv) {
82     if (!WOULD_LOG(VERBOSE)) return;
83     for (int i = 0; i < argc; i++) {
84         LOG(VERBOSE) << __func__ << ": argv[" << i << "]=" << (argv[i] ? argv[i] : "null");
85     }
86 }
87 
checkAndClearUseLocalNameserversFlag(unsigned * netid)88 bool checkAndClearUseLocalNameserversFlag(unsigned* netid) {
89     if (netid == nullptr || ((*netid) & NETID_USE_LOCAL_NAMESERVERS) == 0) {
90         return false;
91     }
92     *netid = (*netid) & ~NETID_USE_LOCAL_NAMESERVERS;
93     return true;
94 }
95 
requestingUseLocalNameservers(unsigned flags)96 constexpr bool requestingUseLocalNameservers(unsigned flags) {
97     return (flags & NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS) != 0;
98 }
99 
queryingViaTls(unsigned dns_netid)100 bool queryingViaTls(unsigned dns_netid) {
101     const auto privateDnsStatus = PrivateDnsConfiguration::getInstance().getStatus(dns_netid);
102     switch (privateDnsStatus.mode) {
103         case PrivateDnsMode::OPPORTUNISTIC:
104             return !privateDnsStatus.validatedServers().empty();
105         case PrivateDnsMode::STRICT:
106             return true;
107         default:
108             return false;
109     }
110 }
111 
hasPermissionToBypassPrivateDns(uid_t uid)112 bool hasPermissionToBypassPrivateDns(uid_t uid) {
113     static_assert(AID_SYSTEM >= 0 && AID_SYSTEM < FIRST_APPLICATION_UID,
114                   "Calls from AID_SYSTEM must not result in a permission check to avoid deadlock.");
115     if (uid >= 0 && uid < FIRST_APPLICATION_UID) {
116         return true;
117     }
118 
119     for (const char* const permission :
120          {PERM_CONNECTIVITY_USE_RESTRICTED_NETWORKS, PERM_NETWORK_BYPASS_PRIVATE_DNS,
121           PERM_MAINLINE_NETWORK_STACK}) {
122         if (gResNetdCallbacks.check_calling_permission(permission)) {
123             return true;
124         }
125     }
126     return false;
127 }
128 
maybeFixupNetContext(android_net_context * ctx,pid_t pid)129 void maybeFixupNetContext(android_net_context* ctx, pid_t pid) {
130     if (requestingUseLocalNameservers(ctx->flags) && !hasPermissionToBypassPrivateDns(ctx->uid)) {
131         // Not permitted; clear the flag.
132         ctx->flags &= ~NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
133     }
134 
135     if (!requestingUseLocalNameservers(ctx->flags)) {
136         // If we're not explicitly bypassing DNS-over-TLS servers, check whether
137         // DNS-over-TLS is in use as an indicator for when to use more modern
138         // DNS resolution mechanics.
139         if (queryingViaTls(ctx->dns_netid)) {
140             ctx->flags |= NET_CONTEXT_FLAG_USE_DNS_OVER_TLS | NET_CONTEXT_FLAG_USE_EDNS;
141         }
142     }
143     ctx->pid = pid;
144 }
145 
146 void addIpAddrWithinLimit(std::vector<std::string>* ip_addrs, const sockaddr* addr,
147                           socklen_t addrlen);
148 
extractResNsendAnswers(std::span<const uint8_t> answer,int ipType,std::vector<std::string> * ip_addrs)149 int extractResNsendAnswers(std::span<const uint8_t> answer, int ipType,
150                            std::vector<std::string>* ip_addrs) {
151     int total_ip_addr_count = 0;
152     ns_msg handle;
153     if (ns_initparse(answer.data(), answer.size(), &handle) < 0) {
154         return 0;
155     }
156     int ancount = ns_msg_count(handle, ns_s_an);
157     ns_rr rr;
158     for (int i = 0; i < ancount; i++) {
159         if (ns_parserr(&handle, ns_s_an, i, &rr) < 0) {
160             continue;
161         }
162         const uint8_t* rdata = ns_rr_rdata(rr);
163         if (ipType == ns_t_a) {
164             sockaddr_in sin = {.sin_family = AF_INET};
165             memcpy(&sin.sin_addr, rdata, sizeof(sin.sin_addr));
166             addIpAddrWithinLimit(ip_addrs, (sockaddr*)&sin, sizeof(sin));
167             total_ip_addr_count++;
168         } else if (ipType == ns_t_aaaa) {
169             sockaddr_in6 sin6 = {.sin6_family = AF_INET6};
170             memcpy(&sin6.sin6_addr, rdata, sizeof(sin6.sin6_addr));
171             addIpAddrWithinLimit(ip_addrs, (sockaddr*)&sin6, sizeof(sin6));
172             total_ip_addr_count++;
173         }
174     }
175 
176     return total_ip_addr_count;
177 }
178 
extractGetAddrInfoAnswers(const addrinfo * result,std::vector<std::string> * ip_addrs)179 int extractGetAddrInfoAnswers(const addrinfo* result, std::vector<std::string>* ip_addrs) {
180     int total_ip_addr_count = 0;
181     if (result == nullptr) {
182         return 0;
183     }
184     for (const addrinfo* ai = result; ai; ai = ai->ai_next) {
185         sockaddr* ai_addr = ai->ai_addr;
186         if (ai_addr) {
187             addIpAddrWithinLimit(ip_addrs, ai_addr, ai->ai_addrlen);
188             total_ip_addr_count++;
189         }
190     }
191     return total_ip_addr_count;
192 }
193 
extractGetHostByNameAnswers(const hostent * hp,std::vector<std::string> * ip_addrs)194 int extractGetHostByNameAnswers(const hostent* hp, std::vector<std::string>* ip_addrs) {
195     int total_ip_addr_count = 0;
196     if (hp == nullptr) {
197         return 0;
198     }
199     if (hp->h_addrtype == AF_INET) {
200         in_addr** list = (in_addr**)hp->h_addr_list;
201         for (int i = 0; list[i] != nullptr; i++) {
202             sockaddr_in sin = {.sin_family = AF_INET, .sin_addr = *list[i]};
203             addIpAddrWithinLimit(ip_addrs, (sockaddr*)&sin, sizeof(sin));
204             total_ip_addr_count++;
205         }
206     } else if (hp->h_addrtype == AF_INET6) {
207         in6_addr** list = (in6_addr**)hp->h_addr_list;
208         for (int i = 0; list[i] != nullptr; i++) {
209             sockaddr_in6 sin6 = {.sin6_family = AF_INET6, .sin6_addr = *list[i]};
210             addIpAddrWithinLimit(ip_addrs, (sockaddr*)&sin6, sizeof(sin6));
211             total_ip_addr_count++;
212         }
213     }
214     return total_ip_addr_count;
215 }
216 
rcodeToAiError(int rcode)217 int rcodeToAiError(int rcode) {
218     switch (rcode) {
219         case NOERROR:
220             return 0;
221         case RCODE_TIMEOUT:
222             return NETD_RESOLV_TIMEOUT;
223         default:
224             return EAI_NODATA;
225     }
226 }
227 
resNSendToAiError(int err,int rcode)228 int resNSendToAiError(int err, int rcode) {
229     if (err > 0) {
230         return rcodeToAiError(rcode);
231     }
232     if (err == -ETIMEDOUT) {
233         return NETD_RESOLV_TIMEOUT;
234     }
235     return EAI_SYSTEM;
236 }
237 
238 template <typename IntegralType>
simpleStrtoul(const char * input,IntegralType * output,int base=10)239 bool simpleStrtoul(const char* input, IntegralType* output, int base = 10) {
240     char* endPtr;
241     errno = 0;
242     auto result = strtoul(input, &endPtr, base);
243     // Check the length in order to ensure there is no "-" sign
244     if (!*input || *endPtr || (endPtr - input) != static_cast<ptrdiff_t>(strlen(input)) ||
245         (errno == ERANGE && (result == ULONG_MAX))) {
246         return false;
247     }
248     *output = result;
249     return true;
250 }
251 
setQueryId(span<uint8_t> msg,uint16_t query_id)252 bool setQueryId(span<uint8_t> msg, uint16_t query_id) {
253     if ((size_t)msg.size() < sizeof(HEADER)) {
254         errno = EINVAL;
255         return false;
256     }
257     auto hp = reinterpret_cast<HEADER*>(msg.data());
258     hp->id = htons(query_id);
259     return true;
260 }
261 
parseQuery(span<const uint8_t> msg,uint16_t * query_id,int * rr_type,std::string * rr_name)262 bool parseQuery(span<const uint8_t> msg, uint16_t* query_id, int* rr_type, std::string* rr_name) {
263     ns_msg handle;
264     ns_rr rr;
265     if (ns_initparse(msg.data(), msg.size(), &handle) < 0 ||
266         ns_parserr(&handle, ns_s_qd, 0, &rr) < 0) {
267         return false;
268     }
269     *query_id = ns_msg_id(handle);
270     *rr_name = ns_rr_name(rr);
271     *rr_type = ns_rr_type(rr);
272     return true;
273 }
274 
275 // Note: Even if it returns PDM_OFF, it doesn't mean there's no DoT stats in the message
276 // because Private DNS mode can change at any time.
getPrivateDnsModeForMetrics(uint32_t netId)277 PrivateDnsModes getPrivateDnsModeForMetrics(uint32_t netId) {
278     switch (PrivateDnsConfiguration::getInstance().getStatus(netId).mode) {
279         case PrivateDnsMode::OFF:
280             // It can also be due to netId not found.
281             return PrivateDnsModes::PDM_OFF;
282         case PrivateDnsMode::OPPORTUNISTIC:
283             return PrivateDnsModes::PDM_OPPORTUNISTIC;
284         case PrivateDnsMode::STRICT:
285             return PrivateDnsModes::PDM_STRICT;
286         default:
287             return PrivateDnsModes::PDM_UNKNOWN;
288     }
289 }
290 
initDnsEvent(NetworkDnsEventReported * event,const android_net_context & netContext)291 void initDnsEvent(NetworkDnsEventReported* event, const android_net_context& netContext) {
292     // The value 0 has the special meaning of unset/unknown in Statsd atoms. So, we set both
293     // flags to -1 as default value.
294     //  1. The hints flag is only used in resolv_getaddrinfo. When user set it to -1 in
295     //     resolv_getaddrinfo, the flag will cause validation (validateHints) failure in
296     //     getaddrinfo, so it will not do DNS query and will upload DNS stats log with
297     //     return_code = RC_EAI_BADFLAGS.
298     //  2. The res_nsend flags are only used in resolv_res_nsend. When user set it to -1 in
299     //     resolv_res_nsend,res_nsend will do nothing special by the setting.
300     event->set_hints_ai_flags(-1);
301     event->set_res_nsend_flags(-1);
302     event->set_private_dns_modes(getPrivateDnsModeForMetrics(netContext.dns_netid));
303 }
304 
305 // Return 0 if the event should not be logged.
306 // Otherwise, return subsampling_denom
getDnsEventSubsamplingRate(int netid,int returnCode,bool isMdns)307 uint32_t getDnsEventSubsamplingRate(int netid, int returnCode, bool isMdns) {
308     uint32_t subsampling_denom = resolv_cache_get_subsampling_denom(netid, returnCode, isMdns);
309     if (subsampling_denom == 0) return 0;
310     // Sample the event with a chance of 1 / denom.
311     return (arc4random_uniform(subsampling_denom) == 0) ? subsampling_denom : 0;
312 }
313 
maybeLogQuery(int eventType,const android_net_context & netContext,const NetworkDnsEventReported & event,const std::string & query_name,const std::vector<std::string> & ip_addrs)314 void maybeLogQuery(int eventType, const android_net_context& netContext,
315                    const NetworkDnsEventReported& event, const std::string& query_name,
316                    const std::vector<std::string>& ip_addrs) {
317     // Skip reverse queries.
318     if (eventType == INetdEventListener::EVENT_GETHOSTBYADDR) return;
319 
320     for (const auto& query : event.dns_query_events().dns_query_event()) {
321         // Log it when the cache misses.
322         if (query.cache_hit() != CS_FOUND) {
323             const int timeTakenMs = event.latency_micros() / 1000;
324             DnsQueryLog::Record record(netContext.dns_netid, netContext.uid, netContext.pid,
325                                        query_name, ip_addrs, timeTakenMs);
326             gDnsResolv->dnsQueryLog().push(std::move(record));
327             return;
328         }
329     }
330 }
331 
reportDnsEvent(int eventType,const android_net_context & netContext,int latencyUs,int returnCode,NetworkDnsEventReported & event,const std::string & query_name,const std::vector<std::string> & ip_addrs={},int total_ip_addr_count=0)332 void reportDnsEvent(int eventType, const android_net_context& netContext, int latencyUs,
333                     int returnCode, NetworkDnsEventReported& event, const std::string& query_name,
334                     const std::vector<std::string>& ip_addrs = {}, int total_ip_addr_count = 0) {
335     uint32_t rate =
336             (query_name.ends_with(".local") && is_mdns_supported_network(netContext.dns_netid) &&
337              android::net::Experiments::getInstance()->getFlag("mdns_resolution", 1))
338                     ? getDnsEventSubsamplingRate(netContext.dns_netid, returnCode, true)
339                     : getDnsEventSubsamplingRate(netContext.dns_netid, returnCode, false);
340 
341     if (rate) {
342         const std::string& dnsQueryStats = event.dns_query_events().SerializeAsString();
343         stats::BytesField dnsQueryBytesField{dnsQueryStats.c_str(), dnsQueryStats.size()};
344         event.set_return_code(static_cast<ReturnCode>(returnCode));
345         event.set_network_type(resolv_get_network_types_for_net(netContext.dns_netid));
346         android::net::stats::stats_write(android::net::stats::NETWORK_DNS_EVENT_REPORTED,
347                                          event.event_type(), event.return_code(),
348                                          event.latency_micros(), event.hints_ai_flags(),
349                                          event.res_nsend_flags(), event.network_type(),
350                                          event.private_dns_modes(), dnsQueryBytesField, rate);
351     }
352 
353     maybeLogQuery(eventType, netContext, event, query_name, ip_addrs);
354 
355     const auto& listeners = ResolverEventReporter::getInstance().getListeners();
356     if (listeners.empty()) {
357         LOG(ERROR) << __func__
358                    << ": DNS event not sent since no INetdEventListener receiver is available.";
359     }
360     const int latencyMs = latencyUs / 1000;
361     for (const auto& it : listeners) {
362         it->onDnsEvent(netContext.dns_netid, eventType, returnCode, latencyMs, query_name, ip_addrs,
363                        total_ip_addr_count, netContext.uid);
364     }
365 
366     const auto& unsolEventListeners = ResolverEventReporter::getInstance().getUnsolEventListeners();
367 
368     if (returnCode == NETD_RESOLV_TIMEOUT) {
369         const DnsHealthEventParcel dnsHealthEvent = {
370                 .netId = static_cast<int32_t>(netContext.dns_netid),
371                 .healthResult = IDnsResolverUnsolicitedEventListener::DNS_HEALTH_RESULT_TIMEOUT,
372         };
373         for (const auto& it : unsolEventListeners) {
374             it->onDnsHealthEvent(dnsHealthEvent);
375         }
376     } else if (returnCode == NOERROR) {
377         DnsHealthEventParcel dnsHealthEvent = {
378                 .netId = static_cast<int32_t>(netContext.dns_netid),
379                 .healthResult = IDnsResolverUnsolicitedEventListener::DNS_HEALTH_RESULT_OK,
380         };
381         for (const auto& query : event.dns_query_events().dns_query_event()) {
382             if (query.cache_hit() != CS_FOUND && query.rcode() == NS_R_NO_ERROR) {
383                 dnsHealthEvent.successRttMicros.push_back(query.latency_micros());
384             }
385         }
386 
387         if (!dnsHealthEvent.successRttMicros.empty()) {
388             for (const auto& it : unsolEventListeners) {
389                 it->onDnsHealthEvent(dnsHealthEvent);
390             }
391         }
392     }
393 }
394 
onlyIPv4Answers(const addrinfo * res)395 bool onlyIPv4Answers(const addrinfo* res) {
396     // Null addrinfo pointer isn't checked because the caller doesn't pass null pointer.
397 
398     for (const addrinfo* ai = res; ai; ai = ai->ai_next)
399         if (ai->ai_family != AF_INET) return false;
400 
401     return true;
402 }
403 
isSpecialUseIPv4Address(const struct in_addr & ia)404 bool isSpecialUseIPv4Address(const struct in_addr& ia) {
405     const uint32_t addr = ntohl(ia.s_addr);
406 
407     // Only check necessary IP ranges in RFC 5735 section 4
408     return ((addr & 0xff000000) == 0x00000000) ||  // "This" Network
409            ((addr & 0xff000000) == 0x7f000000) ||  // Loopback
410            ((addr & 0xffff0000) == 0xa9fe0000) ||  // Link Local
411            ((addr & 0xf0000000) == 0xe0000000) ||  // Multicast
412            (addr == INADDR_BROADCAST);             // Limited Broadcast
413 }
414 
isSpecialUseIPv4Address(const struct sockaddr * sa)415 bool isSpecialUseIPv4Address(const struct sockaddr* sa) {
416     if (sa->sa_family != AF_INET) return false;
417 
418     return isSpecialUseIPv4Address(((struct sockaddr_in*)sa)->sin_addr);
419 }
420 
onlyNonSpecialUseIPv4Addresses(struct hostent * hp)421 bool onlyNonSpecialUseIPv4Addresses(struct hostent* hp) {
422     // Null hostent pointer isn't checked because the caller doesn't pass null pointer.
423 
424     if (hp->h_addrtype != AF_INET) return false;
425 
426     for (int i = 0; hp->h_addr_list[i] != nullptr; i++)
427         if (isSpecialUseIPv4Address(*(struct in_addr*)hp->h_addr_list[i])) return false;
428 
429     return true;
430 }
431 
onlyNonSpecialUseIPv4Addresses(const addrinfo * res)432 bool onlyNonSpecialUseIPv4Addresses(const addrinfo* res) {
433     // Null addrinfo pointer isn't checked because the caller doesn't pass null pointer.
434 
435     for (const addrinfo* ai = res; ai; ai = ai->ai_next) {
436         if (ai->ai_family != AF_INET) return false;
437         if (isSpecialUseIPv4Address(ai->ai_addr)) return false;
438     }
439 
440     return true;
441 }
442 
logDnsQueryResult(const struct hostent * hp)443 void logDnsQueryResult(const struct hostent* hp) {
444     if (!WOULD_LOG(DEBUG)) return;
445     if (hp == nullptr) return;
446 
447     LOG(DEBUG) << __func__ << ": DNS records:";
448     for (int i = 0; hp->h_addr_list[i] != nullptr; i++) {
449         char ip_addr[INET6_ADDRSTRLEN];
450         if (inet_ntop(hp->h_addrtype, hp->h_addr_list[i], ip_addr, sizeof(ip_addr)) != nullptr) {
451             LOG(DEBUG) << __func__ << ": [" << i << "] " << hp->h_addrtype;
452         } else {
453             PLOG(DEBUG) << __func__ << ": [" << i << "] numeric hostname translation fail";
454         }
455     }
456 }
457 
logDnsQueryResult(const addrinfo * res)458 void logDnsQueryResult(const addrinfo* res) {
459     if (!WOULD_LOG(DEBUG)) return;
460     if (res == nullptr) return;
461 
462     int i;
463     const addrinfo* ai;
464     LOG(DEBUG) << __func__ << ": DNS records:";
465     for (ai = res, i = 0; ai; ai = ai->ai_next, i++) {
466         if ((ai->ai_family != AF_INET) && (ai->ai_family != AF_INET6)) continue;
467         char ip_addr[INET6_ADDRSTRLEN];
468         int ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, ip_addr, sizeof(ip_addr), nullptr, 0,
469                               NI_NUMERICHOST);
470         if (!ret) {
471             LOG(DEBUG) << __func__ << ": [" << i << "] " << ai->ai_flags << " " << ai->ai_family
472                        << " " << ai->ai_socktype << " " << ai->ai_protocol;
473         } else {
474             LOG(DEBUG) << __func__ << ": [" << i << "] numeric hostname translation fail " << ret;
475         }
476     }
477 }
478 
isValidNat64Prefix(const netdutils::IPPrefix prefix)479 bool isValidNat64Prefix(const netdutils::IPPrefix prefix) {
480     if (prefix.family() != AF_INET6) {
481         LOG(ERROR) << __func__ << ": Only IPv6 NAT64 prefixes are supported " << prefix.family();
482         return false;
483     }
484     if (prefix.length() != 96) {
485         LOG(ERROR) << __func__ << ": Only /96 NAT64 prefixes are supported " << prefix.length();
486         return false;
487     }
488     return true;
489 }
490 
synthesizeNat64PrefixWithARecord(const netdutils::IPPrefix & prefix,struct hostent * hp)491 bool synthesizeNat64PrefixWithARecord(const netdutils::IPPrefix& prefix, struct hostent* hp) {
492     if (hp == nullptr) return false;
493     if (!onlyNonSpecialUseIPv4Addresses(hp)) return false;
494     if (!isValidNat64Prefix(prefix)) return false;
495 
496     struct sockaddr_storage ss = netdutils::IPSockAddr(prefix.ip());
497     struct sockaddr_in6* v6prefix = (struct sockaddr_in6*)&ss;
498     for (int i = 0; hp->h_addr_list[i] != nullptr; i++) {
499         struct in_addr iaOriginal = *(struct in_addr*)hp->h_addr_list[i];
500         struct in6_addr* ia6 = (struct in6_addr*)hp->h_addr_list[i];
501         memset(ia6, 0, sizeof(struct in6_addr));
502 
503         // Synthesize /96 NAT64 prefix in place. The space has reserved by getanswer() and
504         // _hf_gethtbyname2() in system/netd/resolv/gethnamaddr.cpp and
505         // system/netd/resolv/sethostent.cpp.
506         *ia6 = v6prefix->sin6_addr;
507         ia6->s6_addr32[3] = iaOriginal.s_addr;
508 
509         if (WOULD_LOG(VERBOSE)) {
510             char buf[INET6_ADDRSTRLEN];  // big enough for either IPv4 or IPv6
511             inet_ntop(AF_INET, &iaOriginal.s_addr, buf, sizeof(buf));
512             LOG(VERBOSE) << __func__ << ": DNS A record: " << buf;
513             inet_ntop(AF_INET6, &v6prefix->sin6_addr, buf, sizeof(buf));
514             LOG(VERBOSE) << __func__ << ": NAT64 prefix: " << buf;
515             inet_ntop(AF_INET6, ia6, buf, sizeof(buf));
516             LOG(VERBOSE) << __func__ << ": DNS64 Synthesized AAAA record: " << buf;
517         }
518     }
519     hp->h_addrtype = AF_INET6;
520     hp->h_length = sizeof(in6_addr);
521 
522     logDnsQueryResult(hp);
523     return true;
524 }
525 
synthesizeNat64PrefixWithARecord(const netdutils::IPPrefix & prefix,addrinfo * result)526 bool synthesizeNat64PrefixWithARecord(const netdutils::IPPrefix& prefix, addrinfo* result) {
527     if (result == nullptr) return false;
528     if (!onlyNonSpecialUseIPv4Addresses(result)) return false;
529     if (!isValidNat64Prefix(prefix)) return false;
530 
531     struct sockaddr_storage ss = netdutils::IPSockAddr(prefix.ip());
532     struct sockaddr_in6* v6prefix = (struct sockaddr_in6*)&ss;
533     for (addrinfo* ai = result; ai; ai = ai->ai_next) {
534         struct sockaddr_in sinOriginal = *(struct sockaddr_in*)ai->ai_addr;
535         struct sockaddr_in6* sin6 = (struct sockaddr_in6*)ai->ai_addr;
536         memset(sin6, 0, sizeof(sockaddr_in6));
537 
538         // Synthesize /96 NAT64 prefix in place. The space has reserved by get_ai() in
539         // system/netd/resolv/getaddrinfo.cpp.
540         sin6->sin6_addr = v6prefix->sin6_addr;
541         sin6->sin6_addr.s6_addr32[3] = sinOriginal.sin_addr.s_addr;
542         sin6->sin6_family = AF_INET6;
543         sin6->sin6_port = sinOriginal.sin_port;
544         ai->ai_addrlen = sizeof(struct sockaddr_in6);
545         ai->ai_family = AF_INET6;
546 
547         if (WOULD_LOG(VERBOSE)) {
548             char buf[INET6_ADDRSTRLEN];  // big enough for either IPv4 or IPv6
549             inet_ntop(AF_INET, &sinOriginal.sin_addr.s_addr, buf, sizeof(buf));
550             LOG(VERBOSE) << __func__ << ": DNS A record: " << buf;
551             inet_ntop(AF_INET6, &v6prefix->sin6_addr, buf, sizeof(buf));
552             LOG(VERBOSE) << __func__ << ": NAT64 prefix: " << buf;
553             inet_ntop(AF_INET6, &sin6->sin6_addr, buf, sizeof(buf));
554             LOG(VERBOSE) << __func__ << ": DNS64 Synthesized AAAA record: " << buf;
555         }
556     }
557     logDnsQueryResult(result);
558     return true;
559 }
560 
getDns64Prefix(unsigned netId,netdutils::IPPrefix * prefix)561 bool getDns64Prefix(unsigned netId, netdutils::IPPrefix* prefix) {
562     return !gDnsResolv->resolverCtrl.getPrefix64(netId, prefix);
563 }
564 
makeThreadName(unsigned netId,uint32_t uid)565 std::string makeThreadName(unsigned netId, uint32_t uid) {
566     // The maximum of netId and app_id are 5-digit numbers.
567     return fmt::format("Dns_{}_{}", netId, multiuser_get_app_id(uid));
568 }
569 
570 }  // namespace
571 
DnsProxyListener()572 DnsProxyListener::DnsProxyListener() : FrameworkListener(SOCKET_NAME) {
573     registerCmd(new GetAddrInfoCmd());
574     registerCmd(new GetHostByAddrCmd());
575     registerCmd(new GetHostByNameCmd());
576     registerCmd(new ResNSendCommand());
577     registerCmd(new GetDnsNetIdCommand());
578 }
579 
spawn()580 void DnsProxyListener::Handler::spawn() {
581     const int rval = netdutils::threadLaunch(this);
582     if (rval == 0) {
583         return;
584     }
585 
586     char* msg = nullptr;
587     asprintf(&msg, "%s (%d)", strerror(-rval), -rval);
588     mClient->sendMsg(ResponseCode::OperationFailed, msg, false);
589     free(msg);
590     delete this;
591 }
592 
GetAddrInfoHandler(SocketClient * c,std::string host,std::string service,std::unique_ptr<addrinfo> hints,const android_net_context & netcontext)593 DnsProxyListener::GetAddrInfoHandler::GetAddrInfoHandler(SocketClient* c, std::string host,
594                                                          std::string service,
595                                                          std::unique_ptr<addrinfo> hints,
596                                                          const android_net_context& netcontext)
597     : Handler(c),
598       mHost(move(host)),
599       mService(move(service)),
600       mHints(move(hints)),
601       mNetContext(netcontext) {}
602 
evaluate_domain_name(const android_net_context & netcontext,const char * host)603 static bool evaluate_domain_name(const android_net_context& netcontext, const char* host) {
604     if (!gResNetdCallbacks.evaluate_domain_name) return true;
605     return gResNetdCallbacks.evaluate_domain_name(netcontext, host);
606 }
607 
sendBE32(SocketClient * c,uint32_t data)608 static bool sendBE32(SocketClient* c, uint32_t data) {
609     uint32_t be_data = htonl(data);
610     return c->sendData(&be_data, sizeof(be_data)) == 0;
611 }
612 
613 // Sends 4 bytes of big-endian length, followed by the data.
614 // Returns true on success.
sendLenAndData(SocketClient * c,const int len,const void * data)615 static bool sendLenAndData(SocketClient* c, const int len, const void* data) {
616     return sendBE32(c, len) && (len == 0 || c->sendData(data, len) == 0);
617 }
618 
619 // Returns true on success
sendhostent(SocketClient * c,hostent * hp)620 static bool sendhostent(SocketClient* c, hostent* hp) {
621     bool success = true;
622     int i;
623     if (hp->h_name != nullptr) {
624         success &= sendLenAndData(c, strlen(hp->h_name) + 1, hp->h_name);
625     } else {
626         success &= sendLenAndData(c, 0, "") == 0;
627     }
628 
629     for (i = 0; hp->h_aliases[i] != nullptr; i++) {
630         success &= sendLenAndData(c, strlen(hp->h_aliases[i]) + 1, hp->h_aliases[i]);
631     }
632     success &= sendLenAndData(c, 0, "");  // null to indicate we're done
633 
634     uint32_t buf = htonl(hp->h_addrtype);
635     success &= c->sendData(&buf, sizeof(buf)) == 0;
636 
637     buf = htonl(hp->h_length);
638     success &= c->sendData(&buf, sizeof(buf)) == 0;
639 
640     for (i = 0; hp->h_addr_list[i] != nullptr; i++) {
641         success &= sendLenAndData(c, 16, hp->h_addr_list[i]);
642     }
643     success &= sendLenAndData(c, 0, "");  // null to indicate we're done
644     return success;
645 }
646 
sendaddrinfo(SocketClient * c,addrinfo * ai)647 static bool sendaddrinfo(SocketClient* c, addrinfo* ai) {
648     // struct addrinfo {
649     //      int     ai_flags;       /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
650     //      int     ai_family;      /* PF_xxx */
651     //      int     ai_socktype;    /* SOCK_xxx */
652     //      int     ai_protocol;    /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
653     //      socklen_t ai_addrlen;   /* length of ai_addr */
654     //      char    *ai_canonname;  /* canonical name for hostname */
655     //      struct  sockaddr *ai_addr;      /* binary address */
656     //      struct  addrinfo *ai_next;      /* next structure in linked list */
657     // };
658 
659     // Write the struct piece by piece because we might be a 64-bit netd
660     // talking to a 32-bit process.
661     bool success = sendBE32(c, ai->ai_flags) && sendBE32(c, ai->ai_family) &&
662                    sendBE32(c, ai->ai_socktype) && sendBE32(c, ai->ai_protocol);
663     if (!success) {
664         return false;
665     }
666 
667     // ai_addrlen and ai_addr.
668     if (!sendLenAndData(c, ai->ai_addrlen, ai->ai_addr)) {
669         return false;
670     }
671 
672     // strlen(ai_canonname) and ai_canonname.
673     if (!sendLenAndData(c, ai->ai_canonname ? strlen(ai->ai_canonname) + 1 : 0, ai->ai_canonname)) {
674         return false;
675     }
676 
677     return true;
678 }
679 
doDns64Synthesis(int32_t * rv,addrinfo ** res,NetworkDnsEventReported * event)680 void DnsProxyListener::GetAddrInfoHandler::doDns64Synthesis(int32_t* rv, addrinfo** res,
681                                                             NetworkDnsEventReported* event) {
682     const bool ipv6WantedButNoData = (mHints && mHints->ai_family == AF_INET6 && *rv == EAI_NODATA);
683     const bool unspecWantedButNoIPv6 =
684             ((!mHints || mHints->ai_family == AF_UNSPEC) && *rv == 0 && onlyIPv4Answers(*res));
685 
686     if (!ipv6WantedButNoData && !unspecWantedButNoIPv6) {
687         return;
688     }
689 
690     netdutils::IPPrefix prefix{};
691     if (!getDns64Prefix(mNetContext.dns_netid, &prefix)) {
692         return;
693     }
694 
695     if (ipv6WantedButNoData) {
696         // If caller wants IPv6 answers but no data, try to query IPv4 answers for synthesis
697         const uid_t uid = mClient->getUid();
698         if (queryLimiter.start(uid)) {
699             const char* host = mHost.starts_with('^') ? nullptr : mHost.c_str();
700             const char* service = mService.starts_with('^') ? nullptr : mService.c_str();
701             mHints->ai_family = AF_INET;
702             // Don't need to do freeaddrinfo(res) before starting new DNS lookup because previous
703             // DNS lookup is failed with error EAI_NODATA.
704             *rv = resolv_getaddrinfo(host, service, mHints.get(), &mNetContext, res, event);
705             queryLimiter.finish(uid);
706             if (*rv) {
707                 *rv = EAI_NODATA;  // return original error code
708                 return;
709             }
710         } else {
711             LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached";
712             return;
713         }
714     }
715 
716     if (!synthesizeNat64PrefixWithARecord(prefix, *res)) {
717         if (ipv6WantedButNoData) {
718             // If caller wants IPv6 answers but no data and failed to synthesize IPv6 answers,
719             // don't return the IPv4 answers.
720             *rv = EAI_NODATA;  // return original error code
721             if (*res) {
722                 freeaddrinfo(*res);
723                 *res = nullptr;
724             }
725         }
726     }
727 }
728 
run()729 void DnsProxyListener::GetAddrInfoHandler::run() {
730     LOG(DEBUG) << "GetAddrInfoHandler::run: {" << mNetContext.app_netid << " "
731                << mNetContext.app_mark << " " << mNetContext.dns_netid << " "
732                << mNetContext.dns_mark << " " << mNetContext.uid << " " << mNetContext.flags << "}";
733 
734     addrinfo* result = nullptr;
735     Stopwatch s;
736     maybeFixupNetContext(&mNetContext, mClient->getPid());
737     const uid_t uid = mClient->getUid();
738     int32_t rv = 0;
739     NetworkDnsEventReported event;
740     initDnsEvent(&event, mNetContext);
741     if (queryLimiter.start(uid)) {
742         const char* host = mHost.starts_with('^') ? nullptr : mHost.c_str();
743         const char* service = mService.starts_with('^') ? nullptr : mService.c_str();
744         if (evaluate_domain_name(mNetContext, host)) {
745             rv = resolv_getaddrinfo(host, service, mHints.get(), &mNetContext, &result, &event);
746         } else {
747             rv = EAI_SYSTEM;
748         }
749         queryLimiter.finish(uid);
750     } else {
751         // Note that this error code is currently not passed down to the client.
752         // android_getaddrinfo_proxy() returns EAI_NODATA on any error.
753         rv = EAI_MEMORY;
754         LOG(ERROR) << "GetAddrInfoHandler::run: from UID " << uid
755                    << ", max concurrent queries reached";
756     }
757 
758     doDns64Synthesis(&rv, &result, &event);
759     const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
760     event.set_latency_micros(latencyUs);
761     event.set_event_type(EVENT_GETADDRINFO);
762     event.set_hints_ai_flags((mHints ? mHints->ai_flags : 0));
763 
764     bool success = true;
765     if (rv) {
766         // getaddrinfo failed
767         success = !mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, &rv, sizeof(rv));
768     } else {
769         success = !mClient->sendCode(ResponseCode::DnsProxyQueryResult);
770         addrinfo* ai = result;
771         while (ai && success) {
772             success = sendBE32(mClient, 1) && sendaddrinfo(mClient, ai);
773             ai = ai->ai_next;
774         }
775         success = success && sendBE32(mClient, 0);
776     }
777 
778     if (!success) {
779         PLOG(WARNING) << "GetAddrInfoHandler::run: Error writing DNS result to client uid " << uid
780                       << " pid " << mClient->getPid();
781     }
782 
783     std::vector<std::string> ip_addrs;
784     const int total_ip_addr_count = extractGetAddrInfoAnswers(result, &ip_addrs);
785     reportDnsEvent(INetdEventListener::EVENT_GETADDRINFO, mNetContext, latencyUs, rv, event, mHost,
786                    ip_addrs, total_ip_addr_count);
787     freeaddrinfo(result);
788 }
789 
threadName()790 std::string DnsProxyListener::GetAddrInfoHandler::threadName() {
791     return makeThreadName(mNetContext.dns_netid, mClient->getUid());
792 }
793 
794 namespace {
795 
addIpAddrWithinLimit(std::vector<std::string> * ip_addrs,const sockaddr * addr,socklen_t addrlen)796 void addIpAddrWithinLimit(std::vector<std::string>* ip_addrs, const sockaddr* addr,
797                           socklen_t addrlen) {
798     // ipAddresses array is limited to first INetdEventListener::DNS_REPORTED_IP_ADDRESSES_LIMIT
799     // addresses for A and AAAA. Total count of addresses is provided, to be able to tell whether
800     // some addresses didn't get logged.
801     if (ip_addrs->size() < INetdEventListener::DNS_REPORTED_IP_ADDRESSES_LIMIT) {
802         char ip_addr[INET6_ADDRSTRLEN];
803         if (getnameinfo(addr, addrlen, ip_addr, sizeof(ip_addr), nullptr, 0, NI_NUMERICHOST) == 0) {
804             ip_addrs->push_back(std::string(ip_addr));
805         }
806     }
807 }
808 
809 }  // namespace
810 
GetAddrInfoCmd()811 DnsProxyListener::GetAddrInfoCmd::GetAddrInfoCmd() : FrameworkCommand("getaddrinfo") {}
812 
runCommand(SocketClient * cli,int argc,char ** argv)813 int DnsProxyListener::GetAddrInfoCmd::runCommand(SocketClient* cli, int argc, char** argv) {
814     logArguments(argc, argv);
815 
816     if (argc != 8) {
817         char* msg = nullptr;
818         asprintf(&msg, "Invalid number of arguments to getaddrinfo: %i", argc);
819         LOG(WARNING) << "GetAddrInfoCmd::runCommand: " << (msg ? msg : "null");
820         cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
821         free(msg);
822         return -1;
823     }
824 
825     const std::string name = argv[1];
826     const std::string service = argv[2];
827     int ai_flags = strtol(argv[3], nullptr, 10);
828     int ai_family = strtol(argv[4], nullptr, 10);
829     int ai_socktype = strtol(argv[5], nullptr, 10);
830     int ai_protocol = strtol(argv[6], nullptr, 10);
831     unsigned netId = strtoul(argv[7], nullptr, 10);
832     const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
833     const uid_t uid = cli->getUid();
834 
835     android_net_context netcontext;
836     gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
837 
838     if (useLocalNameservers) {
839         netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
840     }
841 
842     std::unique_ptr<addrinfo> hints;
843     if (ai_flags != -1 || ai_family != -1 || ai_socktype != -1 || ai_protocol != -1) {
844         hints.reset((addrinfo*)calloc(1, sizeof(addrinfo)));
845         hints->ai_flags = ai_flags;
846         hints->ai_family = ai_family;
847         hints->ai_socktype = ai_socktype;
848         hints->ai_protocol = ai_protocol;
849     }
850 
851     (new GetAddrInfoHandler(cli, name, service, move(hints), netcontext))->spawn();
852     return 0;
853 }
854 
855 /*******************************************************
856  *                  ResNSendCommand                    *
857  *******************************************************/
ResNSendCommand()858 DnsProxyListener::ResNSendCommand::ResNSendCommand() : FrameworkCommand("resnsend") {}
859 
runCommand(SocketClient * cli,int argc,char ** argv)860 int DnsProxyListener::ResNSendCommand::runCommand(SocketClient* cli, int argc, char** argv) {
861     logArguments(argc, argv);
862 
863     const uid_t uid = cli->getUid();
864     if (argc != 4) {
865         LOG(WARNING) << "ResNSendCommand::runCommand: resnsend: from UID " << uid
866                      << ", invalid number of arguments to resnsend: " << argc;
867         sendBE32(cli, -EINVAL);
868         return -1;
869     }
870 
871     unsigned netId;
872     if (!simpleStrtoul(argv[1], &netId)) {
873         LOG(WARNING) << "ResNSendCommand::runCommand: resnsend: from UID " << uid
874                      << ", invalid netId";
875         sendBE32(cli, -EINVAL);
876         return -1;
877     }
878 
879     uint32_t flags;
880     if (!simpleStrtoul(argv[2], &flags)) {
881         LOG(WARNING) << "ResNSendCommand::runCommand: resnsend: from UID " << uid
882                      << ", invalid flags";
883         sendBE32(cli, -EINVAL);
884         return -1;
885     }
886 
887     const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
888 
889     android_net_context netcontext;
890     gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
891 
892     if (useLocalNameservers) {
893         netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
894     }
895 
896     (new ResNSendHandler(cli, argv[3], flags, netcontext))->spawn();
897     return 0;
898 }
899 
ResNSendHandler(SocketClient * c,std::string msg,uint32_t flags,const android_net_context & netcontext)900 DnsProxyListener::ResNSendHandler::ResNSendHandler(SocketClient* c, std::string msg, uint32_t flags,
901                                                    const android_net_context& netcontext)
902     : Handler(c), mMsg(std::move(msg)), mFlags(flags), mNetContext(netcontext) {}
903 
run()904 void DnsProxyListener::ResNSendHandler::run() {
905     LOG(DEBUG) << "ResNSendHandler::run: " << mFlags << " / {" << mNetContext.app_netid << " "
906                << mNetContext.app_mark << " " << mNetContext.dns_netid << " "
907                << mNetContext.dns_mark << " " << mNetContext.uid << " " << mNetContext.flags << "}";
908 
909     Stopwatch s;
910     maybeFixupNetContext(&mNetContext, mClient->getPid());
911 
912     // Decode
913     std::vector<uint8_t> msg(MAXPACKET, 0);
914 
915     // Max length of mMsg is less than 1024 since the CMD_BUF_SIZE in FrameworkListener is 1024
916     int msgLen = b64_pton(mMsg.c_str(), msg.data(), MAXPACKET);
917     if (msgLen == -1) {
918         // Decode fail
919         sendBE32(mClient, -EILSEQ);
920         return;
921     }
922 
923     const uid_t uid = mClient->getUid();
924     int rr_type = 0;
925     std::string rr_name;
926     uint16_t original_query_id = 0;
927 
928     // TODO: Handle the case which is msg contains more than one query
929     if (!parseQuery({msg.data(), msgLen}, &original_query_id, &rr_type, &rr_name) ||
930         !setQueryId({msg.data(), msgLen}, arc4random_uniform(65536))) {
931         // If the query couldn't be parsed, block the request.
932         LOG(WARNING) << "ResNSendHandler::run: resnsend: from UID " << uid << ", invalid query";
933         sendBE32(mClient, -EINVAL);
934         return;
935     }
936 
937     // Send DNS query
938     std::vector<uint8_t> ansBuf(MAXPACKET, 0);
939     int rcode = ns_r_noerror;
940     int ansLen = -1;
941     NetworkDnsEventReported event;
942     initDnsEvent(&event, mNetContext);
943     if (queryLimiter.start(uid)) {
944         if (evaluate_domain_name(mNetContext, rr_name.c_str())) {
945             ansLen = resolv_res_nsend(&mNetContext, {msg.data(), msgLen}, ansBuf, &rcode,
946                                       static_cast<ResNsendFlags>(mFlags), &event);
947         } else {
948             ansLen = -EAI_SYSTEM;
949         }
950         queryLimiter.finish(uid);
951     } else {
952         LOG(WARNING) << "ResNSendHandler::run: resnsend: from UID " << uid
953                      << ", max concurrent queries reached";
954         ansLen = -EBUSY;
955     }
956 
957     const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
958     event.set_latency_micros(latencyUs);
959     event.set_event_type(EVENT_RES_NSEND);
960     event.set_res_nsend_flags(static_cast<ResNsendFlags>(mFlags));
961 
962     // Fail, send -errno
963     if (ansLen < 0) {
964         if (!sendBE32(mClient, ansLen)) {
965             PLOG(WARNING) << "ResNSendHandler::run: resnsend: failed to send errno to uid " << uid
966                           << " pid " << mClient->getPid();
967         }
968         if (rr_type == ns_t_a || rr_type == ns_t_aaaa) {
969             reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs,
970                            resNSendToAiError(ansLen, rcode), event, rr_name);
971         }
972         return;
973     }
974 
975     // Send rcode
976     if (!sendBE32(mClient, rcode)) {
977         PLOG(WARNING) << "ResNSendHandler::run: resnsend: failed to send rcode to uid " << uid
978                       << " pid " << mClient->getPid();
979         return;
980     }
981 
982     // Restore query id and send answer
983     if (!setQueryId({ansBuf.data(), ansLen}, original_query_id) ||
984         !sendLenAndData(mClient, ansLen, ansBuf.data())) {
985         PLOG(WARNING) << "ResNSendHandler::run: resnsend: failed to send answer to uid " << uid
986                       << " pid " << mClient->getPid();
987         return;
988     }
989 
990     if (rr_type == ns_t_a || rr_type == ns_t_aaaa) {
991         std::vector<std::string> ip_addrs;
992         const int total_ip_addr_count =
993                 extractResNsendAnswers({ansBuf.data(), ansLen}, rr_type, &ip_addrs);
994         reportDnsEvent(INetdEventListener::EVENT_RES_NSEND, mNetContext, latencyUs,
995                        resNSendToAiError(ansLen, rcode), event, rr_name, ip_addrs,
996                        total_ip_addr_count);
997     }
998 }
999 
threadName()1000 std::string DnsProxyListener::ResNSendHandler::threadName() {
1001     return makeThreadName(mNetContext.dns_netid, mClient->getUid());
1002 }
1003 
1004 namespace {
1005 
sendCodeAndBe32(SocketClient * c,int code,int data)1006 bool sendCodeAndBe32(SocketClient* c, int code, int data) {
1007     return !c->sendCode(code) && sendBE32(c, data);
1008 }
1009 
1010 }  // namespace
1011 
1012 /*******************************************************
1013  *                  GetDnsNetId                        *
1014  *******************************************************/
GetDnsNetIdCommand()1015 DnsProxyListener::GetDnsNetIdCommand::GetDnsNetIdCommand() : FrameworkCommand("getdnsnetid") {}
1016 
runCommand(SocketClient * cli,int argc,char ** argv)1017 int DnsProxyListener::GetDnsNetIdCommand::runCommand(SocketClient* cli, int argc, char** argv) {
1018     logArguments(argc, argv);
1019 
1020     const uid_t uid = cli->getUid();
1021     if (argc != 2) {
1022         LOG(WARNING) << "GetDnsNetIdCommand::runCommand: getdnsnetid: from UID " << uid
1023                      << ", invalid number of arguments to getdnsnetid: " << argc;
1024         sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, -EINVAL);
1025         return -1;
1026     }
1027 
1028     unsigned netId;
1029     if (!simpleStrtoul(argv[1], &netId)) {
1030         LOG(WARNING) << "GetDnsNetIdCommand::runCommand: getdnsnetid: from UID " << uid
1031                      << ", invalid netId";
1032         sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, -EINVAL);
1033         return -1;
1034     }
1035 
1036     const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
1037     android_net_context netcontext;
1038     gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
1039 
1040     if (useLocalNameservers) {
1041         netcontext.app_netid |= NETID_USE_LOCAL_NAMESERVERS;
1042     }
1043 
1044     const bool success =
1045             sendCodeAndBe32(cli, ResponseCode::DnsProxyQueryResult, netcontext.app_netid);
1046     if (!success) {
1047         PLOG(WARNING)
1048                 << "GetDnsNetIdCommand::runCommand: getdnsnetid: failed to send result to uid "
1049                 << uid << " pid " << cli->getPid();
1050     }
1051 
1052     return success ? 0 : -1;
1053 }
1054 
1055 /*******************************************************
1056  *                  GetHostByName                      *
1057  *******************************************************/
GetHostByNameCmd()1058 DnsProxyListener::GetHostByNameCmd::GetHostByNameCmd() : FrameworkCommand("gethostbyname") {}
1059 
runCommand(SocketClient * cli,int argc,char ** argv)1060 int DnsProxyListener::GetHostByNameCmd::runCommand(SocketClient* cli, int argc, char** argv) {
1061     logArguments(argc, argv);
1062 
1063     if (argc != 4) {
1064         char* msg = nullptr;
1065         asprintf(&msg, "Invalid number of arguments to gethostbyname: %i", argc);
1066         LOG(WARNING) << "GetHostByNameCmd::runCommand: " << (msg ? msg : "null");
1067         cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
1068         free(msg);
1069         return -1;
1070     }
1071 
1072     uid_t uid = cli->getUid();
1073     unsigned netId = strtoul(argv[1], nullptr, 10);
1074     const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
1075     std::string name = argv[2];
1076     int af = strtol(argv[3], nullptr, 10);
1077 
1078     android_net_context netcontext;
1079     gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
1080 
1081     if (useLocalNameservers) {
1082         netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
1083     }
1084 
1085     (new GetHostByNameHandler(cli, name, af, netcontext))->spawn();
1086     return 0;
1087 }
1088 
GetHostByNameHandler(SocketClient * c,std::string name,int af,const android_net_context & netcontext)1089 DnsProxyListener::GetHostByNameHandler::GetHostByNameHandler(SocketClient* c, std::string name,
1090                                                              int af,
1091                                                              const android_net_context& netcontext)
1092     : Handler(c), mName(move(name)), mAf(af), mNetContext(netcontext) {}
1093 
doDns64Synthesis(int32_t * rv,hostent * hbuf,char * buf,size_t buflen,struct hostent ** hpp,NetworkDnsEventReported * event)1094 void DnsProxyListener::GetHostByNameHandler::doDns64Synthesis(int32_t* rv, hostent* hbuf, char* buf,
1095                                                               size_t buflen, struct hostent** hpp,
1096                                                               NetworkDnsEventReported* event) {
1097     // Don't have to consider family AF_UNSPEC case because gethostbyname{, 2} only supports
1098     // family AF_INET or AF_INET6.
1099     const bool ipv6WantedButNoData = (mAf == AF_INET6 && *rv == EAI_NODATA);
1100 
1101     if (!ipv6WantedButNoData) {
1102         return;
1103     }
1104 
1105     netdutils::IPPrefix prefix{};
1106     if (!getDns64Prefix(mNetContext.dns_netid, &prefix)) {
1107         return;
1108     }
1109 
1110     // If caller wants IPv6 answers but no data, try to query IPv4 answers for synthesis
1111     const uid_t uid = mClient->getUid();
1112     if (queryLimiter.start(uid)) {
1113         const char* name = mName.starts_with('^') ? nullptr : mName.c_str();
1114         *rv = resolv_gethostbyname(name, AF_INET, hbuf, buf, buflen, &mNetContext, hpp, event);
1115         queryLimiter.finish(uid);
1116         if (*rv) {
1117             *rv = EAI_NODATA;  // return original error code
1118             return;
1119         }
1120     } else {
1121         LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached";
1122         return;
1123     }
1124 
1125     if (!synthesizeNat64PrefixWithARecord(prefix, *hpp)) {
1126         // If caller wants IPv6 answers but no data and failed to synthesize IPv4 answers,
1127         // don't return the IPv4 answers.
1128         *hpp = nullptr;
1129     }
1130 }
1131 
run()1132 void DnsProxyListener::GetHostByNameHandler::run() {
1133     Stopwatch s;
1134     maybeFixupNetContext(&mNetContext, mClient->getPid());
1135     const uid_t uid = mClient->getUid();
1136     hostent* hp = nullptr;
1137     hostent hbuf;
1138     char tmpbuf[MAXPACKET];
1139     int32_t rv = 0;
1140     NetworkDnsEventReported event;
1141     initDnsEvent(&event, mNetContext);
1142     if (queryLimiter.start(uid)) {
1143         const char* name = mName.starts_with('^') ? nullptr : mName.c_str();
1144         if (evaluate_domain_name(mNetContext, name)) {
1145             rv = resolv_gethostbyname(name, mAf, &hbuf, tmpbuf, sizeof tmpbuf, &mNetContext, &hp,
1146                                       &event);
1147         } else {
1148             rv = EAI_SYSTEM;
1149         }
1150         queryLimiter.finish(uid);
1151     } else {
1152         rv = EAI_MEMORY;
1153         LOG(ERROR) << "GetHostByNameHandler::run: from UID " << uid
1154                    << ", max concurrent queries reached";
1155     }
1156 
1157     doDns64Synthesis(&rv, &hbuf, tmpbuf, sizeof tmpbuf, &hp, &event);
1158     const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
1159     event.set_latency_micros(latencyUs);
1160     event.set_event_type(EVENT_GETHOSTBYNAME);
1161 
1162     if (rv) {
1163         LOG(DEBUG) << "GetHostByNameHandler::run: result failed: " << gai_strerror(rv);
1164     }
1165 
1166     bool success = true;
1167     if (hp) {
1168         // hp is not nullptr iff. rv is 0.
1169         success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0;
1170         success &= sendhostent(mClient, hp);
1171     } else {
1172         success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, nullptr, 0) == 0;
1173     }
1174 
1175     if (!success) {
1176         PLOG(WARNING) << "GetHostByNameHandler::run: Error writing DNS result to client uid " << uid
1177                       << " pid " << mClient->getPid();
1178     }
1179 
1180     std::vector<std::string> ip_addrs;
1181     const int total_ip_addr_count = extractGetHostByNameAnswers(hp, &ip_addrs);
1182     reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYNAME, mNetContext, latencyUs, rv, event,
1183                    mName, ip_addrs, total_ip_addr_count);
1184 }
1185 
threadName()1186 std::string DnsProxyListener::GetHostByNameHandler::threadName() {
1187     return makeThreadName(mNetContext.dns_netid, mClient->getUid());
1188 }
1189 
1190 /*******************************************************
1191  *                  GetHostByAddr                      *
1192  *******************************************************/
GetHostByAddrCmd()1193 DnsProxyListener::GetHostByAddrCmd::GetHostByAddrCmd() : FrameworkCommand("gethostbyaddr") {}
1194 
runCommand(SocketClient * cli,int argc,char ** argv)1195 int DnsProxyListener::GetHostByAddrCmd::runCommand(SocketClient* cli, int argc, char** argv) {
1196     logArguments(argc, argv);
1197 
1198     if (argc != 5) {
1199         char* msg = nullptr;
1200         asprintf(&msg, "Invalid number of arguments to gethostbyaddr: %i", argc);
1201         LOG(WARNING) << "GetHostByAddrCmd::runCommand: " << (msg ? msg : "null");
1202         cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
1203         free(msg);
1204         return -1;
1205     }
1206 
1207     char* addrStr = argv[1];
1208     int addrLen = strtol(argv[2], nullptr, 10);
1209     int addrFamily = strtol(argv[3], nullptr, 10);
1210     uid_t uid = cli->getUid();
1211     unsigned netId = strtoul(argv[4], nullptr, 10);
1212     const bool useLocalNameservers = checkAndClearUseLocalNameserversFlag(&netId);
1213 
1214     in6_addr addr;
1215     errno = 0;
1216     int result = inet_pton(addrFamily, addrStr, &addr);
1217     if (result <= 0) {
1218         char* msg = nullptr;
1219         asprintf(&msg, "inet_pton(\"%s\") failed %s", addrStr, strerror(errno));
1220         LOG(WARNING) << "GetHostByAddrCmd::runCommand: " << (msg ? msg : "null");
1221         cli->sendMsg(ResponseCode::OperationFailed, msg, false);
1222         free(msg);
1223         return -1;
1224     }
1225 
1226     android_net_context netcontext;
1227     gResNetdCallbacks.get_network_context(netId, uid, &netcontext);
1228 
1229     if (useLocalNameservers) {
1230         netcontext.flags |= NET_CONTEXT_FLAG_USE_LOCAL_NAMESERVERS;
1231     }
1232 
1233     (new GetHostByAddrHandler(cli, addr, addrLen, addrFamily, netcontext))->spawn();
1234     return 0;
1235 }
1236 
GetHostByAddrHandler(SocketClient * c,in6_addr address,int addressLen,int addressFamily,const android_net_context & netcontext)1237 DnsProxyListener::GetHostByAddrHandler::GetHostByAddrHandler(SocketClient* c, in6_addr address,
1238                                                              int addressLen, int addressFamily,
1239                                                              const android_net_context& netcontext)
1240     : Handler(c),
1241       mAddress(address),
1242       mAddressLen(addressLen),
1243       mAddressFamily(addressFamily),
1244       mNetContext(netcontext) {}
1245 
doDns64ReverseLookup(hostent * hbuf,char * buf,size_t buflen,struct hostent ** hpp,NetworkDnsEventReported * event)1246 void DnsProxyListener::GetHostByAddrHandler::doDns64ReverseLookup(hostent* hbuf, char* buf,
1247                                                                   size_t buflen,
1248                                                                   struct hostent** hpp,
1249                                                                   NetworkDnsEventReported* event) {
1250     if (*hpp != nullptr || mAddressFamily != AF_INET6) {
1251         return;
1252     }
1253 
1254     netdutils::IPPrefix prefix{};
1255     if (!getDns64Prefix(mNetContext.dns_netid, &prefix)) {
1256         return;
1257     }
1258 
1259     if (!isValidNat64Prefix(prefix)) {
1260         return;
1261     }
1262 
1263     struct sockaddr_storage ss = netdutils::IPSockAddr(prefix.ip());
1264     struct sockaddr_in6* v6prefix = (struct sockaddr_in6*)&ss;
1265     struct in6_addr v6addr = mAddress;
1266     // Check if address has NAT64 prefix. Only /96 IPv6 NAT64 prefixes are supported
1267     if ((v6addr.s6_addr32[0] != v6prefix->sin6_addr.s6_addr32[0]) ||
1268         (v6addr.s6_addr32[1] != v6prefix->sin6_addr.s6_addr32[1]) ||
1269         (v6addr.s6_addr32[2] != v6prefix->sin6_addr.s6_addr32[2])) {
1270         return;
1271     }
1272 
1273     const uid_t uid = mClient->getUid();
1274     if (queryLimiter.start(uid)) {
1275         // Remove NAT64 prefix and do reverse DNS query
1276         struct in_addr v4addr = {.s_addr = v6addr.s6_addr32[3]};
1277         resolv_gethostbyaddr(&v4addr, sizeof(v4addr), AF_INET, hbuf, buf, buflen, &mNetContext, hpp,
1278                              event);
1279         queryLimiter.finish(uid);
1280         if (*hpp) {
1281             // Replace IPv4 address with original queried IPv6 address in place. The space has
1282             // reserved by dns_gethtbyaddr() and netbsd_gethostent_r() in
1283             // system/netd/resolv/gethnamaddr.cpp.
1284             // Note that resolv_gethostbyaddr() returns only one entry in result.
1285             memcpy((*hpp)->h_addr_list[0], &v6addr, sizeof(v6addr));
1286             (*hpp)->h_addrtype = AF_INET6;
1287             (*hpp)->h_length = sizeof(struct in6_addr);
1288         }
1289     } else {
1290         LOG(ERROR) << __func__ << ": from UID " << uid << ", max concurrent queries reached";
1291     }
1292 }
1293 
run()1294 void DnsProxyListener::GetHostByAddrHandler::run() {
1295     Stopwatch s;
1296     maybeFixupNetContext(&mNetContext, mClient->getPid());
1297     const uid_t uid = mClient->getUid();
1298     hostent* hp = nullptr;
1299     hostent hbuf;
1300     char tmpbuf[MAXPACKET];
1301     int32_t rv = 0;
1302     NetworkDnsEventReported event;
1303     initDnsEvent(&event, mNetContext);
1304     if (queryLimiter.start(uid)) {
1305         rv = resolv_gethostbyaddr(&mAddress, mAddressLen, mAddressFamily, &hbuf, tmpbuf,
1306                                   sizeof tmpbuf, &mNetContext, &hp, &event);
1307         queryLimiter.finish(uid);
1308     } else {
1309         rv = EAI_MEMORY;
1310         LOG(ERROR) << "GetHostByAddrHandler::run: from UID " << uid
1311                    << ", max concurrent queries reached";
1312     }
1313 
1314     doDns64ReverseLookup(&hbuf, tmpbuf, sizeof tmpbuf, &hp, &event);
1315     const int32_t latencyUs = saturate_cast<int32_t>(s.timeTakenUs());
1316     event.set_latency_micros(latencyUs);
1317     event.set_event_type(EVENT_GETHOSTBYADDR);
1318 
1319     if (rv) {
1320         LOG(DEBUG) << "GetHostByAddrHandler::run: result failed: " << gai_strerror(rv);
1321     }
1322 
1323     bool success = true;
1324     if (hp) {
1325         success = mClient->sendCode(ResponseCode::DnsProxyQueryResult) == 0;
1326         success &= sendhostent(mClient, hp);
1327     } else {
1328         success = mClient->sendBinaryMsg(ResponseCode::DnsProxyOperationFailed, nullptr, 0) == 0;
1329     }
1330 
1331     if (!success) {
1332         PLOG(WARNING) << "GetHostByAddrHandler::run: Error writing DNS result to client uid " << uid
1333                       << " pid " << mClient->getPid();
1334     }
1335 
1336     reportDnsEvent(INetdEventListener::EVENT_GETHOSTBYADDR, mNetContext, latencyUs, rv, event,
1337                    (hp && hp->h_name) ? hp->h_name : "null", {}, 0);
1338 }
1339 
threadName()1340 std::string DnsProxyListener::GetHostByAddrHandler::threadName() {
1341     return makeThreadName(mNetContext.dns_netid, mClient->getUid());
1342 }
1343 
1344 }  // namespace net
1345 }  // namespace android
1346