From 7c77ce630aeaa54ae7fb64540a33b0ef55dddf6e Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 13 Nov 2017 17:18:24 +0100 Subject: [PATCH] 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. --- pdns/pdns_recursor.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index db8084825e..cec4fd581d 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); -- 2.47.2