From: Remi Gacogne Date: Mon, 13 Nov 2017 16:18:24 +0000 (+0100) Subject: rec: Check the remote host on handleGenUDPQueryResponse() X-Git-Tag: dnsdist-1.3.0~132^2~1 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7c77ce630aeaa54ae7fb64540a33b0ef55dddf6e;p=pdns rec: Check the remote host on handleGenUDPQueryResponse() We do connect the socket before sending, but it looks like various kernels have a race condition allowing an attacker to inject a packet between the bind() and the connect() calls, which then does not necessarily comes from the expected host. Have fun. --- diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index db8084825..cec4fd581 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -295,7 +295,15 @@ static void handleGenUDPQueryResponse(int fd, FDMultiplexer::funcparam_t& var) { PacketID pident=*any_cast(&var); char resp[512]; - ssize_t ret=recv(fd, resp, sizeof(resp), 0); + ComboAddress fromaddr; + socklen_t addrlen=sizeof(fromaddr); + + ssize_t ret=recvfrom(fd, resp, sizeof(resp), 0, (sockaddr *)&fromaddr, &addrlen); + if (fromaddr != pident.remote) { + L<removeReadFD(fd); if(ret >= 0) { string data(resp, (size_t) ret); @@ -319,6 +327,7 @@ string GenUDPQueryResponse(const ComboAddress& dest, const string& query) PacketID pident; pident.sock=&s; + pident.remote=dest; pident.type=0; t_fdm->addReadFD(s.getHandle(), handleGenUDPQueryResponse, pident);