Skip to content

Commit

Permalink
Don't send structs containing pointers over sockets.
Browse files Browse the repository at this point in the history
Fixes x86-64 netd.

Change-Id: Iee5ef802ebbf2e000b2593643de4eec46f296c04
  • Loading branch information
enh-google committed Nov 13, 2014
1 parent 4bcd2b1 commit fe74301
Showing 1 changed file with 45 additions and 10 deletions.
55 changes: 45 additions & 10 deletions server/DnsProxyListener.cpp
Expand Up @@ -83,12 +83,15 @@ void* DnsProxyListener::GetAddrInfoHandler::threadStart(void* obj) {
return NULL;
}

static bool sendBE32(SocketClient* c, uint32_t data) {
uint32_t be_data = htonl(data);
return c->sendData(&be_data, sizeof(be_data)) == 0;
}

// Sends 4 bytes of big-endian length, followed by the data.
// Returns true on success.
static bool sendLenAndData(SocketClient *c, const int len, const void* data) {
uint32_t len_be = htonl(len);
return c->sendData(&len_be, 4) == 0 &&
(len == 0 || c->sendData(data, len) == 0);
static bool sendLenAndData(SocketClient* c, const int len, const void* data) {
return sendBE32(c, len) && (len == 0 || c->sendData(data, len) == 0);
}

// Returns true on success
Expand Down Expand Up @@ -119,6 +122,42 @@ static bool sendhostent(SocketClient *c, struct hostent *hp) {
return success;
}

static bool sendaddrinfo(SocketClient* c, struct addrinfo* ai) {
// struct addrinfo {
// int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
// int ai_family; /* PF_xxx */
// int ai_socktype; /* SOCK_xxx */
// int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
// socklen_t ai_addrlen; /* length of ai_addr */
// char *ai_canonname; /* canonical name for hostname */
// struct sockaddr *ai_addr; /* binary address */
// struct addrinfo *ai_next; /* next structure in linked list */
// };

// Write the struct piece by piece because we might be a 64-bit netd
// talking to a 32-bit process.
bool success =
sendBE32(c, ai->ai_flags) &&
sendBE32(c, ai->ai_family) &&
sendBE32(c, ai->ai_socktype) &&
sendBE32(c, ai->ai_protocol);
if (!success) {
return false;
}

// ai_addrlen and ai_addr.
if (!sendLenAndData(c, ai->ai_addrlen, ai->ai_addr)) {
return false;
}

// strlen(ai_canonname) and ai_canonname.
if (!sendLenAndData(c, ai->ai_canonname ? strlen(ai->ai_canonname) + 1 : 0, ai->ai_canonname)) {
return false;
}

return true;
}

void DnsProxyListener::GetAddrInfoHandler::run() {
if (DBG) {
ALOGD("GetAddrInfoHandler, now for %s / %s / %u / %u", mHost, mService, mNetId, mMark);
Expand All @@ -133,14 +172,10 @@ void DnsProxyListener::GetAddrInfoHandler::run() {
bool success = !mClient->sendCode(ResponseCode::DnsProxyQueryResult);
struct addrinfo* ai = result;
while (ai && success) {
success = sendLenAndData(mClient, sizeof(struct addrinfo), ai)
&& sendLenAndData(mClient, ai->ai_addrlen, ai->ai_addr)
&& sendLenAndData(mClient,
ai->ai_canonname ? strlen(ai->ai_canonname) + 1 : 0,
ai->ai_canonname);
success = sendBE32(mClient, 1) && sendaddrinfo(mClient, ai);
ai = ai->ai_next;
}
success = success && sendLenAndData(mClient, 0, "");
success = success && sendBE32(mClient, 0);
if (!success) {
ALOGW("Error writing DNS result to client");
}
Expand Down

0 comments on commit fe74301

Please sign in to comment.