Subject: | Runaway rapid memory growth when handling Net::DNS::Packet |
Date: | Sat, 11 Oct 2014 10:54:42 +0100 |
To: | bug-Net-DNS [...] rt.cpan.org |
From: | John McEleney <john.mceleney [...] netservers.co.uk> |
I originally reported this bug over at Redhat's bugzilla because I was
using Fedora. However, I've since determined that this bug also occurs
on Ubuntu Trusty when version 0.80 of Net::DNS is used. Under Ubuntu I
built Net::DNS 0.80 on the host from CPAN, so this is not a bug
introduced downstream.
Original report: https://bugzilla.redhat.com/show_bug.cgi?id=1151572
Description of problem:
When I query the NS records for a certain domain using
Net::DNS::Resolver::Recurse, the perl process gets stuck in a infinite
loop, rapidly expanding in size until it is killed by the OOM killer.
How reproducible:
Can be reproduced every time you query certain domain(s). I've now
reproduced it on Ubuntu Trusty, and four different Fedora 20 systems,
one of which was a virgin system booted from the Fedora Live DVD.
The problem does _not_ occur on CentOS/RHEL 6.5 or CentOS/RHEL 7 which
ship with Net::DNS versions lower that 0.80.
Steps to Reproduce:
1. Create a perl script that queries NS records for domain
villamontanavista.co.uk
2. Run the script
3. Watch top and see the script grow in size until the OOM killer steps in.
Actual results:
Perl script devours all available memory until it is killed by OOM Killer
Expected results:
DNS records should be handled by the script and it should exit almost
instantly
Additional info:
This perl script will always trigger the bug:
=========================
#!/usr/bin/perl
use strict;
use Net::DNS;
use Net::DNS::Resolver::Recurse;
use Data::Dumper;
select STDERR; $| = 1;
select STDOUT; $| = 1;
my $res = Net::DNS::Resolver::Recurse->new;
$res->hints();
$res->recursion_callback(sub {
my $packet = shift;
print "==============\n".Dumper($packet)."\n--------------------\n";
for ($packet->additional){ print $_->string."\n"; }
});
$res->tcp_timeout(10);
$res->udp_timeout(10);
print "Starting recursion\n";
my $packet=$res->query_dorecursion("villamontanavista.co.uk","NS");
print "Finished recursion\n";
=========================
Some strace output (goes on like this until killed):
brk(0) = 0x18a1000
brk(0x18c2000) = 0x18c2000
brk(0) = 0x18c2000
brk(0x18e3000) = 0x18e3000
brk(0) = 0x18e3000
brk(0x1904000) = 0x1904000
brk(0) = 0x1904000
brk(0x1925000) = 0x1925000
brk(0) = 0x1925000
brk(0x1946000) = 0x1946000
brk(0) = 0x1946000
brk(0x1967000) = 0x1967000
brk(0) = 0x1967000
brk(0x1988000) = 0x1988000
brk(0) = 0x1988000
--
-----------------------------
John McEleney
Netservers Ltd.
21 Signet Court
Cambridge
CB5 8LA
http://www.netservers.co.uk
-----------------------------
Tel. 01223 446000
Fax. 0870 4861970
-----------------------------
Registered in England
Number: 04028770
-----------------------------