mirror of
https://github.com/moparisthebest/curl
synced 2024-12-22 16:18:48 -05:00
Brad House's validation that DNS response address matches the request address
This commit is contained in:
parent
f164260eee
commit
423a18cecc
12
ares/CHANGES
12
ares/CHANGES
@ -1,5 +1,17 @@
|
||||
Changelog for the c-ares project
|
||||
|
||||
* Aug 25 2008 (Yang Tse)
|
||||
- Improvement by Brad House:
|
||||
|
||||
This patch addresses an issue in which a response could be sent back to the
|
||||
source port of a client from a different address than the request was made to.
|
||||
This is one form of a DNS cache poisoning attack.
|
||||
|
||||
The patch simply uses recvfrom() rather than recv() and validates that the
|
||||
address returned from recvfrom() matches the address of the server we have
|
||||
connected to. Only necessary on UDP sockets as they are connection-less, TCP
|
||||
is unaffected.
|
||||
|
||||
* Aug 4 2008 (Daniel Stenberg)
|
||||
- Fix by Tofu Linden:
|
||||
|
||||
|
@ -9,6 +9,7 @@ This is what's new and changed in the c-ares 1.5.3 release:
|
||||
o library will now be built with _REENTRANT symbol defined if needed
|
||||
o Improved configure detection of number of arguments for getservbyport_r
|
||||
o Improved query-ID randomness
|
||||
o Validate that DNS response address matches the request address
|
||||
|
||||
Thanks go to these friendly people for their efforts and contributions:
|
||||
|
||||
|
@ -429,6 +429,8 @@ static void read_udp_packets(ares_channel channel, fd_set *read_fds,
|
||||
int i;
|
||||
ssize_t count;
|
||||
unsigned char buf[PACKETSZ + 1];
|
||||
struct sockaddr_in from;
|
||||
socklen_t fromlen;
|
||||
|
||||
if(!read_fds && (read_fd == ARES_SOCKET_BAD))
|
||||
/* no possible action */
|
||||
@ -462,11 +464,23 @@ static void read_udp_packets(ares_channel channel, fd_set *read_fds,
|
||||
/* To reduce event loop overhead, read and process as many
|
||||
* packets as we can. */
|
||||
do {
|
||||
count = sread(server->udp_socket, buf, sizeof(buf));
|
||||
/* Must memset 'from' to 0 as recvfrom() on some systems may
|
||||
* not use 'from' at all if it doesn't support receiving the
|
||||
* source address of the response */
|
||||
memset(&from, 0, sizeof(from));
|
||||
fromlen = sizeof(from);
|
||||
count = (ssize_t)recvfrom(server->udp_socket, (void *)buf, sizeof(buf),
|
||||
0, (struct sockaddr *)&from, &fromlen);
|
||||
if (count == -1 && try_again(SOCKERRNO))
|
||||
continue;
|
||||
else if (count <= 0)
|
||||
handle_error(channel, i, now);
|
||||
else if (fromlen && from.sin_addr.s_addr != 0 &&
|
||||
from.sin_addr.s_addr != server->addr.s_addr)
|
||||
/* Address response came from did not match the address
|
||||
* we sent the request to. Someone may be attempting
|
||||
* to perform a cache poisoning attack */
|
||||
break;
|
||||
else
|
||||
process_answer(channel, buf, (int)count, i, 0, now);
|
||||
} while (count > 0);
|
||||
|
Loading…
Reference in New Issue
Block a user