Loading DnsProxyListener.cpp +25 −5 Original line number Original line Diff line number Diff line Loading @@ -535,6 +535,13 @@ DnsProxyListener::GetAddrInfoHandler::~GetAddrInfoHandler() { free(mHints); free(mHints); } } static bool evaluate_domain_name(const android_net_context &netcontext, const char *host) { if (!gResNetdCallbacks.evaluate_domain_name) return true; return gResNetdCallbacks.evaluate_domain_name(netcontext, host); } static bool sendBE32(SocketClient* c, uint32_t data) { static bool sendBE32(SocketClient* c, uint32_t data) { uint32_t be_data = htonl(data); uint32_t be_data = htonl(data); return c->sendData(&be_data, sizeof(be_data)) == 0; return c->sendData(&be_data, sizeof(be_data)) == 0; Loading Loading @@ -672,7 +679,12 @@ void DnsProxyListener::GetAddrInfoHandler::run() { NetworkDnsEventReported event; NetworkDnsEventReported event; initDnsEvent(&event); initDnsEvent(&event); if (queryLimiter.start(uid)) { if (queryLimiter.start(uid)) { rv = resolv_getaddrinfo(mHost, mService, mHints, &mNetContext, &result, &event); if (evaluate_domain_name(mNetContext, mHost)) { rv = resolv_getaddrinfo(mHost, mService, mHints, &mNetContext, &result, &event); } else { rv = EAI_SYSTEM; } queryLimiter.finish(uid); queryLimiter.finish(uid); } else { } else { // Note that this error code is currently not passed down to the client. // Note that this error code is currently not passed down to the client. Loading Loading @@ -887,8 +899,12 @@ void DnsProxyListener::ResNSendHandler::run() { NetworkDnsEventReported event; NetworkDnsEventReported event; initDnsEvent(&event); initDnsEvent(&event); if (queryLimiter.start(uid)) { if (queryLimiter.start(uid)) { if (evaluate_domain_name(mNetContext, rr_name.c_str())) { nsendAns = resolv_res_nsend(&mNetContext, msg.data(), msgLen, ansBuf.data(), MAXPACKET, nsendAns = resolv_res_nsend(&mNetContext, msg.data(), msgLen, ansBuf.data(), MAXPACKET, &rcode, static_cast<ResNsendFlags>(mFlags), &event); &rcode, static_cast<ResNsendFlags>(mFlags), &event); } else { nsendAns = -EAI_SYSTEM; } queryLimiter.finish(uid); queryLimiter.finish(uid); } else { } else { LOG(WARNING) << "ResNSendHandler::run: resnsend: from UID " << uid LOG(WARNING) << "ResNSendHandler::run: resnsend: from UID " << uid Loading Loading @@ -1080,8 +1096,12 @@ void DnsProxyListener::GetHostByNameHandler::run() { NetworkDnsEventReported event; NetworkDnsEventReported event; initDnsEvent(&event); initDnsEvent(&event); if (queryLimiter.start(uid)) { if (queryLimiter.start(uid)) { if (evaluate_domain_name(mNetContext, mName)) { rv = resolv_gethostbyname(mName, mAf, &hbuf, tmpbuf, sizeof tmpbuf, &mNetContext, &hp, rv = resolv_gethostbyname(mName, mAf, &hbuf, tmpbuf, sizeof tmpbuf, &mNetContext, &hp, &event); &event); } else { rv = EAI_SYSTEM; } queryLimiter.finish(uid); queryLimiter.finish(uid); } else { } else { rv = EAI_MEMORY; rv = EAI_MEMORY; Loading DnsResolver.cpp +1 −0 Original line number Original line Diff line number Diff line Loading @@ -38,6 +38,7 @@ bool resolv_init(const ResolverNetdCallbacks* callbacks) { gResNetdCallbacks.log = callbacks->log; gResNetdCallbacks.log = callbacks->log; if (gApiLevel >= 30) { if (gApiLevel >= 30) { gResNetdCallbacks.tagSocket = callbacks->tagSocket; gResNetdCallbacks.tagSocket = callbacks->tagSocket; gResNetdCallbacks.evaluate_domain_name = callbacks->evaluate_domain_name; } } android::net::gDnsResolv = android::net::DnsResolver::getInstance(); android::net::gDnsResolv = android::net::DnsResolver::getInstance(); return android::net::gDnsResolv->start(); return android::net::gDnsResolv->start(); Loading include/netd_resolv/resolv.h +24 −0 Original line number Original line Diff line number Diff line Loading @@ -81,6 +81,29 @@ typedef void (*get_network_context_callback)(unsigned netid, uid_t uid, typedef void (*log_callback)(const char* msg); typedef void (*log_callback)(const char* msg); typedef int (*tagSocketCallback)(int sockFd, uint32_t tag, uid_t uid, pid_t pid); typedef int (*tagSocketCallback)(int sockFd, uint32_t tag, uid_t uid, pid_t pid); // The DnsResolver module invokes this callback once before starting each DNS // lookup. The callback receives the android_net_context associated with the // request, and the (possibly unqualified) hostname requested by the app via // getaddrinfo() or gethostbyname(). // // If the callback returns false, the DnsResolver will abort the request // returning EAI_SYSTEM. If the callback returns true, the query will proceed as // usual. // // If this callback is not present (i.e. set to nullptr), the effect is the same // of returning true. // // This callback *will* be invoked concurrently from multiple threads. It must // peform its own locking when accessing shared data structures. Furthermore, // the callback must not sleep nor perform RPC requests. // // Be mindful that hostnames could contain sensitive user data. Do not log them // and do not transmit them to third parties without explicit user // authorization. // typedef bool (*evaluate_domain_name_callback)( const android_net_context &netcontext, const char *host); /* /* * Some functions needed by the resolver (e.g. checkCallingPermission()) live in * Some functions needed by the resolver (e.g. checkCallingPermission()) live in * libraries with no ABI stability guarantees, such as libbinder.so. * libraries with no ABI stability guarantees, such as libbinder.so. Loading @@ -92,6 +115,7 @@ struct ResolverNetdCallbacks { get_network_context_callback get_network_context; get_network_context_callback get_network_context; log_callback log; log_callback log; tagSocketCallback tagSocket; tagSocketCallback tagSocket; evaluate_domain_name_callback evaluate_domain_name; }; }; #define TAG_SYSTEM_DNS 0xFFFFFF82 #define TAG_SYSTEM_DNS 0xFFFFFF82 Loading Loading
DnsProxyListener.cpp +25 −5 Original line number Original line Diff line number Diff line Loading @@ -535,6 +535,13 @@ DnsProxyListener::GetAddrInfoHandler::~GetAddrInfoHandler() { free(mHints); free(mHints); } } static bool evaluate_domain_name(const android_net_context &netcontext, const char *host) { if (!gResNetdCallbacks.evaluate_domain_name) return true; return gResNetdCallbacks.evaluate_domain_name(netcontext, host); } static bool sendBE32(SocketClient* c, uint32_t data) { static bool sendBE32(SocketClient* c, uint32_t data) { uint32_t be_data = htonl(data); uint32_t be_data = htonl(data); return c->sendData(&be_data, sizeof(be_data)) == 0; return c->sendData(&be_data, sizeof(be_data)) == 0; Loading Loading @@ -672,7 +679,12 @@ void DnsProxyListener::GetAddrInfoHandler::run() { NetworkDnsEventReported event; NetworkDnsEventReported event; initDnsEvent(&event); initDnsEvent(&event); if (queryLimiter.start(uid)) { if (queryLimiter.start(uid)) { rv = resolv_getaddrinfo(mHost, mService, mHints, &mNetContext, &result, &event); if (evaluate_domain_name(mNetContext, mHost)) { rv = resolv_getaddrinfo(mHost, mService, mHints, &mNetContext, &result, &event); } else { rv = EAI_SYSTEM; } queryLimiter.finish(uid); queryLimiter.finish(uid); } else { } else { // Note that this error code is currently not passed down to the client. // Note that this error code is currently not passed down to the client. Loading Loading @@ -887,8 +899,12 @@ void DnsProxyListener::ResNSendHandler::run() { NetworkDnsEventReported event; NetworkDnsEventReported event; initDnsEvent(&event); initDnsEvent(&event); if (queryLimiter.start(uid)) { if (queryLimiter.start(uid)) { if (evaluate_domain_name(mNetContext, rr_name.c_str())) { nsendAns = resolv_res_nsend(&mNetContext, msg.data(), msgLen, ansBuf.data(), MAXPACKET, nsendAns = resolv_res_nsend(&mNetContext, msg.data(), msgLen, ansBuf.data(), MAXPACKET, &rcode, static_cast<ResNsendFlags>(mFlags), &event); &rcode, static_cast<ResNsendFlags>(mFlags), &event); } else { nsendAns = -EAI_SYSTEM; } queryLimiter.finish(uid); queryLimiter.finish(uid); } else { } else { LOG(WARNING) << "ResNSendHandler::run: resnsend: from UID " << uid LOG(WARNING) << "ResNSendHandler::run: resnsend: from UID " << uid Loading Loading @@ -1080,8 +1096,12 @@ void DnsProxyListener::GetHostByNameHandler::run() { NetworkDnsEventReported event; NetworkDnsEventReported event; initDnsEvent(&event); initDnsEvent(&event); if (queryLimiter.start(uid)) { if (queryLimiter.start(uid)) { if (evaluate_domain_name(mNetContext, mName)) { rv = resolv_gethostbyname(mName, mAf, &hbuf, tmpbuf, sizeof tmpbuf, &mNetContext, &hp, rv = resolv_gethostbyname(mName, mAf, &hbuf, tmpbuf, sizeof tmpbuf, &mNetContext, &hp, &event); &event); } else { rv = EAI_SYSTEM; } queryLimiter.finish(uid); queryLimiter.finish(uid); } else { } else { rv = EAI_MEMORY; rv = EAI_MEMORY; Loading
DnsResolver.cpp +1 −0 Original line number Original line Diff line number Diff line Loading @@ -38,6 +38,7 @@ bool resolv_init(const ResolverNetdCallbacks* callbacks) { gResNetdCallbacks.log = callbacks->log; gResNetdCallbacks.log = callbacks->log; if (gApiLevel >= 30) { if (gApiLevel >= 30) { gResNetdCallbacks.tagSocket = callbacks->tagSocket; gResNetdCallbacks.tagSocket = callbacks->tagSocket; gResNetdCallbacks.evaluate_domain_name = callbacks->evaluate_domain_name; } } android::net::gDnsResolv = android::net::DnsResolver::getInstance(); android::net::gDnsResolv = android::net::DnsResolver::getInstance(); return android::net::gDnsResolv->start(); return android::net::gDnsResolv->start(); Loading
include/netd_resolv/resolv.h +24 −0 Original line number Original line Diff line number Diff line Loading @@ -81,6 +81,29 @@ typedef void (*get_network_context_callback)(unsigned netid, uid_t uid, typedef void (*log_callback)(const char* msg); typedef void (*log_callback)(const char* msg); typedef int (*tagSocketCallback)(int sockFd, uint32_t tag, uid_t uid, pid_t pid); typedef int (*tagSocketCallback)(int sockFd, uint32_t tag, uid_t uid, pid_t pid); // The DnsResolver module invokes this callback once before starting each DNS // lookup. The callback receives the android_net_context associated with the // request, and the (possibly unqualified) hostname requested by the app via // getaddrinfo() or gethostbyname(). // // If the callback returns false, the DnsResolver will abort the request // returning EAI_SYSTEM. If the callback returns true, the query will proceed as // usual. // // If this callback is not present (i.e. set to nullptr), the effect is the same // of returning true. // // This callback *will* be invoked concurrently from multiple threads. It must // peform its own locking when accessing shared data structures. Furthermore, // the callback must not sleep nor perform RPC requests. // // Be mindful that hostnames could contain sensitive user data. Do not log them // and do not transmit them to third parties without explicit user // authorization. // typedef bool (*evaluate_domain_name_callback)( const android_net_context &netcontext, const char *host); /* /* * Some functions needed by the resolver (e.g. checkCallingPermission()) live in * Some functions needed by the resolver (e.g. checkCallingPermission()) live in * libraries with no ABI stability guarantees, such as libbinder.so. * libraries with no ABI stability guarantees, such as libbinder.so. Loading @@ -92,6 +115,7 @@ struct ResolverNetdCallbacks { get_network_context_callback get_network_context; get_network_context_callback get_network_context; log_callback log; log_callback log; tagSocketCallback tagSocket; tagSocketCallback tagSocket; evaluate_domain_name_callback evaluate_domain_name; }; }; #define TAG_SYSTEM_DNS 0xFFFFFF82 #define TAG_SYSTEM_DNS 0xFFFFFF82 Loading