Skip Menu |

This queue is for tickets about the Net-DNS CPAN distribution.

Report information
The Basics
Id: 71796
Status: resolved
Priority: 0/
Queue: Net-DNS

People
Owner: Nobody in particular
Requestors: bbb [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: SECURITY: Net::DNS::Nameserver - Race Condition - TCP DoS Vulnerability
Date: Wed, 19 Oct 2011 17:55:15 -0600
To: bug-Net-DNS [...] rt.cpan.org
From: Rob Brown <bbb [...] cpan.org>
My Net::DNS::Nameserver process has been sporadically locking up so many times over the past few months. The whole server freezes and refuses to respond, no matter how many UDP queries come in. But I found that manually issuing a few TCP queries will wake up the server and it will begin responding to UDP queries again. But since TCP queries are extremely rare, the effect is permanent silence! I will not release any exploit code for this vulnerability at this time, but here is a patch that actually fixes the problem: --- /usr/lib64/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi/Net/DNS/Nameserver.pm.DoS 2011-10-07 10:01:44.000000000 -0600 +++ /usr/lib64/perl5/vendor_perl/5.8.8/x86_64-linux-thread-multi/Net/DNS/Nameserver.pm.3 2011-10-19 16:52:13.000000000 -0600 @@ -87,6 +87,7 @@ Listen => 64, Proto => "tcp", Reuse => 1, + Blocking => 0, ); if ( $sock_tcp ) { push @sock_tcp, $sock_tcp; This solution is safe because the tcp_connection code already handles the "undef" case gracefully: my $client = $sock->accept; if (not defined $client) { print "TCP connection closed by peer before we could accept it.\n" if $self->{"Verbose"}; return 0; } This is also safe because a server socket that misses the instant accept() but that somehow very soon afterwards suddenly becomes truly ready to be accept()ed will show up in the readable bits for select() and can_read will instantly pick it up on the very next loop. For example, here is a real live process that quit responding several hours ago: root 582 1.7 0.0 40972 7576 ? S Oct18 30:36 \_ /usr/bin/perl /bin/park_dns And here is the strace of what it is choking on: # strace -tt -s1000 -p 582 Process 582 attached - interrupt to quit 14:53:43.564041 accept(18, Simply using telnet or netcat to port 53 on the IP of that file descriptor and closing the connection, immediately frees up the server, and the strace immediately scrolls by with much more useful processing. The reason this is a problem is because select() or IO::Select->can_read can sometimes yield a listen socket that hasn't completed the full TCP 3-way hand shake due to the SOMAXCONN being reached or packet loss or various kernel conditions. I know you are trying to release a new version of Net::DNS soon, but I hope this fix can be included. -- Rob
Hi Rob, It must have been hard to find the cause of this corner case! All my tests confirm that it is safe too. Applied to trunk. It will be in the 0.67 release. I think it is safe to build and try out your own release candidate from trunk if you wish. Regards, -- Willem